mirror of
https://github.com/TecharoHQ/anubis.git
synced 2026-04-22 16:16:41 +00:00
@@ -2,9 +2,7 @@
|
|||||||
// README at: https://github.com/devcontainers/templates/tree/main/src/debian
|
// README at: https://github.com/devcontainers/templates/tree/main/src/debian
|
||||||
{
|
{
|
||||||
"name": "Dev",
|
"name": "Dev",
|
||||||
"dockerComposeFile": [
|
"dockerComposeFile": ["./docker-compose.yaml"],
|
||||||
"./docker-compose.yaml"
|
|
||||||
],
|
|
||||||
"service": "workspace",
|
"service": "workspace",
|
||||||
"workspaceFolder": "/workspace/anubis",
|
"workspaceFolder": "/workspace/anubis",
|
||||||
"postStartCommand": "bash ./.devcontainer/poststart.sh",
|
"postStartCommand": "bash ./.devcontainer/poststart.sh",
|
||||||
|
|||||||
@@ -58,4 +58,3 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: Additional context
|
label: Additional context
|
||||||
description: Add any other context about the problem here.
|
description: Add any other context about the problem here.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
name: Feature request
|
name: Feature request
|
||||||
description: Suggest an idea for this project
|
description: Suggest an idea for this project
|
||||||
title: '[Feature request] '
|
title: "[Feature request] "
|
||||||
|
|
||||||
body:
|
body:
|
||||||
- type: textarea
|
- type: textarea
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
# check-spelling/check-spelling configuration
|
# check-spelling/check-spelling configuration
|
||||||
|
|
||||||
File | Purpose | Format | Info
|
| 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)
|
| [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)
|
| [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)
|
| [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)
|
| [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)
|
| [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)
|
| [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)
|
| [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)
|
| [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)
|
| [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)
|
| [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)
|
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.
|
and then include multiple files inside that directory (with that suffix) to merge multiple files together.
|
||||||
|
|||||||
@@ -2,30 +2,27 @@
|
|||||||
<details><summary>If the flagged items are :exploding_head: false positives</summary>
|
<details><summary>If the flagged items are :exploding_head: false positives</summary>
|
||||||
|
|
||||||
If items relate to a ...
|
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.
|
Please add a file path to the `excludes.txt` file matching the containing file.
|
||||||
|
|
||||||
File paths are Perl 5 Regular Expressions - you can [test](
|
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.
|
||||||
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](
|
`^` 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).
|
||||||
../tree/HEAD/README.md) (on whichever branch you're using).
|
|
||||||
|
|
||||||
* well-formed pattern.
|
- well-formed pattern.
|
||||||
|
|
||||||
If you can write a [pattern](
|
If you can write a [pattern](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns) that would match it,
|
||||||
https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns
|
|
||||||
) that would match it,
|
|
||||||
try adding it to the `patterns.txt` file.
|
try adding it to the `patterns.txt` file.
|
||||||
|
|
||||||
Patterns are Perl 5 Regular Expressions - you can [test](
|
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.
|
||||||
https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your lines.
|
|
||||||
|
|
||||||
Note that patterns can't match multiline strings.
|
Note that patterns can't match multiline strings.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<!-- adoption information-->
|
<!-- adoption information-->
|
||||||
|
|
||||||
:steam_locomotive: If you're seeing this message and your PR is from a branch that doesn't have check-spelling,
|
: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.
|
please merge to your PR's base branch to get the version configured for your repository.
|
||||||
|
|||||||
@@ -24,10 +24,10 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
||||||
with:
|
with:
|
||||||
node-version: '24.11.0'
|
node-version: "24.11.0"
|
||||||
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||||
with:
|
with:
|
||||||
go-version: '1.25.4'
|
go-version: "1.25.4"
|
||||||
|
|
||||||
- name: install node deps
|
- name: install node deps
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
||||||
with:
|
with:
|
||||||
node-version: '24.11.0'
|
node-version: "24.11.0"
|
||||||
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||||
with:
|
with:
|
||||||
go-version: '1.25.4'
|
go-version: "1.25.4"
|
||||||
|
|
||||||
- uses: ko-build/setup-ko@d006021bd0c28d1ce33a07e7943d48b079944c8d # v0.9
|
- uses: ko-build/setup-ko@d006021bd0c28d1ce33a07e7943d48b079944c8d # v0.9
|
||||||
|
|
||||||
|
|||||||
@@ -38,10 +38,10 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
||||||
with:
|
with:
|
||||||
node-version: '24.11.0'
|
node-version: "24.11.0"
|
||||||
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||||
with:
|
with:
|
||||||
go-version: '1.25.4'
|
go-version: "1.25.4"
|
||||||
|
|
||||||
- uses: ko-build/setup-ko@d006021bd0c28d1ce33a07e7943d48b079944c8d # v0.9
|
- uses: ko-build/setup-ko@d006021bd0c28d1ce33a07e7943d48b079944c8d # v0.9
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||||
with:
|
with:
|
||||||
go-version: '1.25.4'
|
go-version: "1.25.4"
|
||||||
|
|
||||||
- name: Check go.mod and go.sum in main directory
|
- name: Check go.mod and go.sum in main directory
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -26,10 +26,10 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
||||||
with:
|
with:
|
||||||
node-version: '24.11.0'
|
node-version: "24.11.0"
|
||||||
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||||
with:
|
with:
|
||||||
go-version: '1.25.4'
|
go-version: "1.25.4"
|
||||||
|
|
||||||
- name: Cache playwright binaries
|
- name: Cache playwright binaries
|
||||||
uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
|
uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
|
||||||
|
|||||||
@@ -27,10 +27,10 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
||||||
with:
|
with:
|
||||||
node-version: '24.11.0'
|
node-version: "24.11.0"
|
||||||
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||||
with:
|
with:
|
||||||
go-version: '1.25.4'
|
go-version: "1.25.4"
|
||||||
|
|
||||||
- name: install node deps
|
- name: install node deps
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
|
||||||
with:
|
with:
|
||||||
node-version: '24.11.0'
|
node-version: "24.11.0"
|
||||||
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||||
with:
|
with:
|
||||||
go-version: '1.25.4'
|
go-version: "1.25.4"
|
||||||
|
|
||||||
- name: install node deps
|
- name: install node deps
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -59,16 +59,16 @@ name: Check Spelling
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- '**'
|
- "**"
|
||||||
tags-ignore:
|
tags-ignore:
|
||||||
- '**'
|
- "**"
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- '**'
|
- "**"
|
||||||
types:
|
types:
|
||||||
- 'opened'
|
- "opened"
|
||||||
- 'reopened'
|
- "reopened"
|
||||||
- 'synchronize'
|
- "synchronize"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
spelling:
|
spelling:
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
|
||||||
with:
|
with:
|
||||||
go-version: '1.25.4'
|
go-version: "1.25.4"
|
||||||
|
|
||||||
- name: Run CI
|
- name: Run CI
|
||||||
run: go run ./utils/cmd/backoff-retry bash test/ssh-ci/rigging.sh ${{ matrix.host }}
|
run: go run ./utils/cmd/backoff-retry bash test/ssh-ci/rigging.sh ${{ matrix.host }}
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ name: zizmor
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- '.github/workflows/*.ya?ml'
|
- ".github/workflows/*.ya?ml"
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- '.github/workflows/*.ya?ml'
|
- ".github/workflows/*.ya?ml"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
zizmor:
|
zizmor:
|
||||||
|
|||||||
@@ -4,7 +4,4 @@
|
|||||||
user_agent_regex: MistralAI-User/.+; \+https\://docs\.mistral\.ai/robots
|
user_agent_regex: MistralAI-User/.+; \+https\://docs\.mistral\.ai/robots
|
||||||
action: ALLOW
|
action: ALLOW
|
||||||
# https://mistral.ai/mistralai-user-ips.json
|
# https://mistral.ai/mistralai-user-ips.json
|
||||||
remote_addresses: [
|
remote_addresses: ["20.240.160.161/32", "20.240.160.1/32"]
|
||||||
"20.240.160.161/32",
|
|
||||||
"20.240.160.1/32",
|
|
||||||
]
|
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
action: ALLOW
|
action: ALLOW
|
||||||
# https://openai.com/chatgpt-user.json
|
# https://openai.com/chatgpt-user.json
|
||||||
# curl 'https://openai.com/chatgpt-user.json' | jq '.prefixes.[].ipv4Prefix' | sed 's/$/,/'
|
# curl 'https://openai.com/chatgpt-user.json' | jq '.prefixes.[].ipv4Prefix' | sed 's/$/,/'
|
||||||
remote_addresses: [
|
remote_addresses:
|
||||||
|
[
|
||||||
"13.65.138.112/28",
|
"13.65.138.112/28",
|
||||||
"23.98.179.16/28",
|
"23.98.179.16/28",
|
||||||
"13.65.138.96/28",
|
"13.65.138.96/28",
|
||||||
|
|||||||
@@ -4,9 +4,5 @@
|
|||||||
user_agent_regex: Perplexity-User/.+; \+https\://perplexity\.ai/perplexity-user
|
user_agent_regex: Perplexity-User/.+; \+https\://perplexity\.ai/perplexity-user
|
||||||
action: ALLOW
|
action: ALLOW
|
||||||
# https://www.perplexity.com/perplexity-user.json
|
# https://www.perplexity.com/perplexity-user.json
|
||||||
remote_addresses: [
|
remote_addresses:
|
||||||
"44.208.221.197/32",
|
["44.208.221.197/32", "34.193.163.52/32", "18.97.21.0/30", "18.97.43.80/29"]
|
||||||
"34.193.163.52/32",
|
|
||||||
"18.97.21.0/30",
|
|
||||||
"18.97.43.80/29",
|
|
||||||
]
|
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
user_agent_regex: Applebot
|
user_agent_regex: Applebot
|
||||||
action: ALLOW
|
action: ALLOW
|
||||||
# https://search.developer.apple.com/applebot.json
|
# https://search.developer.apple.com/applebot.json
|
||||||
remote_addresses: [
|
remote_addresses:
|
||||||
|
[
|
||||||
"17.241.208.160/27",
|
"17.241.208.160/27",
|
||||||
"17.241.193.160/27",
|
"17.241.193.160/27",
|
||||||
"17.241.200.160/27",
|
"17.241.200.160/27",
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
user_agent_regex: \+http\://www\.bing\.com/bingbot\.htm
|
user_agent_regex: \+http\://www\.bing\.com/bingbot\.htm
|
||||||
action: ALLOW
|
action: ALLOW
|
||||||
# https://www.bing.com/toolbox/bingbot.json
|
# https://www.bing.com/toolbox/bingbot.json
|
||||||
remote_addresses: [
|
remote_addresses:
|
||||||
|
[
|
||||||
"157.55.39.0/24",
|
"157.55.39.0/24",
|
||||||
"207.46.13.0/24",
|
"207.46.13.0/24",
|
||||||
"40.77.167.0/24",
|
"40.77.167.0/24",
|
||||||
@@ -30,5 +31,5 @@
|
|||||||
"20.74.197.0/28",
|
"20.74.197.0/28",
|
||||||
"20.15.133.160/27",
|
"20.15.133.160/27",
|
||||||
"40.77.177.0/24",
|
"40.77.177.0/24",
|
||||||
"40.77.178.0/23"
|
"40.77.178.0/23",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
user_agent_regex: DuckDuckBot/1\.1; \(\+http\://duckduckgo\.com/duckduckbot\.html\)
|
user_agent_regex: DuckDuckBot/1\.1; \(\+http\://duckduckgo\.com/duckduckbot\.html\)
|
||||||
action: ALLOW
|
action: ALLOW
|
||||||
# https://duckduckgo.com/duckduckgo-help-pages/results/duckduckbot
|
# https://duckduckgo.com/duckduckgo-help-pages/results/duckduckbot
|
||||||
remote_addresses: [
|
remote_addresses:
|
||||||
|
[
|
||||||
"57.152.72.128/32",
|
"57.152.72.128/32",
|
||||||
"51.8.253.152/32",
|
"51.8.253.152/32",
|
||||||
"40.80.242.63/32",
|
"40.80.242.63/32",
|
||||||
@@ -271,5 +272,5 @@
|
|||||||
"4.213.46.14/32",
|
"4.213.46.14/32",
|
||||||
"172.169.17.165/32",
|
"172.169.17.165/32",
|
||||||
"51.8.71.117/32",
|
"51.8.71.117/32",
|
||||||
"20.3.1.178/32"
|
"20.3.1.178/32",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
user_agent_regex: \+http\://www\.google\.com/bot\.html
|
user_agent_regex: \+http\://www\.google\.com/bot\.html
|
||||||
action: ALLOW
|
action: ALLOW
|
||||||
# https://developers.google.com/static/search/apis/ipranges/googlebot.json
|
# https://developers.google.com/static/search/apis/ipranges/googlebot.json
|
||||||
remote_addresses: [
|
remote_addresses:
|
||||||
|
[
|
||||||
"2001:4860:4801:10::/64",
|
"2001:4860:4801:10::/64",
|
||||||
"2001:4860:4801:11::/64",
|
"2001:4860:4801:11::/64",
|
||||||
"2001:4860:4801:12::/64",
|
"2001:4860:4801:12::/64",
|
||||||
@@ -259,5 +260,5 @@
|
|||||||
"66.249.79.224/27",
|
"66.249.79.224/27",
|
||||||
"66.249.79.32/27",
|
"66.249.79.32/27",
|
||||||
"66.249.79.64/27",
|
"66.249.79.64/27",
|
||||||
"66.249.79.96/27"
|
"66.249.79.96/27",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
- name: internet-archive
|
- name: internet-archive
|
||||||
action: ALLOW
|
action: ALLOW
|
||||||
# https://ipinfo.io/AS7941
|
# https://ipinfo.io/AS7941
|
||||||
remote_addresses: [
|
remote_addresses: ["207.241.224.0/20", "208.70.24.0/21", "2620:0:9c0::/48"]
|
||||||
"207.241.224.0/20",
|
|
||||||
"208.70.24.0/21",
|
|
||||||
"2620:0:9c0::/48"
|
|
||||||
]
|
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
user_agent_regex: \+https\://kagi\.com/bot
|
user_agent_regex: \+https\://kagi\.com/bot
|
||||||
action: ALLOW
|
action: ALLOW
|
||||||
# https://kagi.com/bot
|
# https://kagi.com/bot
|
||||||
remote_addresses: [
|
remote_addresses:
|
||||||
|
[
|
||||||
"216.18.205.234/32",
|
"216.18.205.234/32",
|
||||||
"35.212.27.76/32",
|
"35.212.27.76/32",
|
||||||
"104.254.65.50/32",
|
"104.254.65.50/32",
|
||||||
"209.151.156.194/32"
|
"209.151.156.194/32",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -2,10 +2,11 @@
|
|||||||
user_agent_regex: search\.marginalia\.nu
|
user_agent_regex: search\.marginalia\.nu
|
||||||
action: ALLOW
|
action: ALLOW
|
||||||
# Received directly over email
|
# Received directly over email
|
||||||
remote_addresses: [
|
remote_addresses:
|
||||||
|
[
|
||||||
"193.183.0.162/31",
|
"193.183.0.162/31",
|
||||||
"193.183.0.164/30",
|
"193.183.0.164/30",
|
||||||
"193.183.0.168/30",
|
"193.183.0.168/30",
|
||||||
"193.183.0.172/31",
|
"193.183.0.172/31",
|
||||||
"193.183.0.174/32"
|
"193.183.0.174/32",
|
||||||
]
|
]
|
||||||
@@ -4,7 +4,8 @@
|
|||||||
user_agent_regex: GPTBot/1\.1; \+https\://openai\.com/gptbot
|
user_agent_regex: GPTBot/1\.1; \+https\://openai\.com/gptbot
|
||||||
action: ALLOW
|
action: ALLOW
|
||||||
# https://openai.com/gptbot.json
|
# https://openai.com/gptbot.json
|
||||||
remote_addresses: [
|
remote_addresses:
|
||||||
|
[
|
||||||
"52.230.152.0/24",
|
"52.230.152.0/24",
|
||||||
"20.171.206.0/24",
|
"20.171.206.0/24",
|
||||||
"20.171.207.0/24",
|
"20.171.207.0/24",
|
||||||
|
|||||||
@@ -4,10 +4,11 @@
|
|||||||
user_agent_regex: OAI-SearchBot/1\.0; \+https\://openai\.com/searchbot
|
user_agent_regex: OAI-SearchBot/1\.0; \+https\://openai\.com/searchbot
|
||||||
action: ALLOW
|
action: ALLOW
|
||||||
# https://openai.com/searchbot.json
|
# https://openai.com/searchbot.json
|
||||||
remote_addresses: [
|
remote_addresses:
|
||||||
|
[
|
||||||
"20.42.10.176/28",
|
"20.42.10.176/28",
|
||||||
"172.203.190.128/28",
|
"172.203.190.128/28",
|
||||||
"104.210.140.128/28",
|
"104.210.140.128/28",
|
||||||
"51.8.102.0/24",
|
"51.8.102.0/24",
|
||||||
"135.234.64.0/24"
|
"135.234.64.0/24",
|
||||||
]
|
]
|
||||||
@@ -4,7 +4,8 @@
|
|||||||
user_agent_regex: PerplexityBot/.+; \+https\://perplexity\.ai/perplexitybot
|
user_agent_regex: PerplexityBot/.+; \+https\://perplexity\.ai/perplexitybot
|
||||||
action: ALLOW
|
action: ALLOW
|
||||||
# https://www.perplexity.com/perplexitybot.json
|
# https://www.perplexity.com/perplexitybot.json
|
||||||
remote_addresses: [
|
remote_addresses:
|
||||||
|
[
|
||||||
"107.20.236.150/32",
|
"107.20.236.150/32",
|
||||||
"3.224.62.45/32",
|
"3.224.62.45/32",
|
||||||
"18.210.92.235/32",
|
"18.210.92.235/32",
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
user_agent_regex: UptimeRobot
|
user_agent_regex: UptimeRobot
|
||||||
action: ALLOW
|
action: ALLOW
|
||||||
# https://api.uptimerobot.com/meta/ips
|
# https://api.uptimerobot.com/meta/ips
|
||||||
remote_addresses: [
|
remote_addresses:
|
||||||
|
[
|
||||||
"3.12.251.153/32",
|
"3.12.251.153/32",
|
||||||
"3.20.63.178/32",
|
"3.20.63.178/32",
|
||||||
"3.77.67.4/32",
|
"3.77.67.4/32",
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
import React, { useState, useEffect, useMemo } from 'react';
|
import React, { useState, useEffect, useMemo } from "react";
|
||||||
import styles from './styles.module.css';
|
import styles from "./styles.module.css";
|
||||||
|
|
||||||
// A helper function to perform SHA-256 hashing.
|
// A helper function to perform SHA-256 hashing.
|
||||||
// It takes a string, encodes it, hashes it, and returns a hex string.
|
// It takes a string, encodes it, hashes it, and returns a hex string.
|
||||||
async function sha256(message) {
|
async function sha256(message) {
|
||||||
try {
|
try {
|
||||||
const msgBuffer = new TextEncoder().encode(message);
|
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 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;
|
return hashHex;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Hashing failed:", error);
|
console.error("Hashing failed:", error);
|
||||||
@@ -21,21 +23,42 @@ const generateRandomHex = (bytes = 16) => {
|
|||||||
const buffer = new Uint8Array(bytes);
|
const buffer = new Uint8Array(bytes);
|
||||||
crypto.getRandomValues(buffer);
|
crypto.getRandomValues(buffer);
|
||||||
return Array.from(buffer)
|
return Array.from(buffer)
|
||||||
.map(byte => byte.toString(16).padStart(2, '0'))
|
.map((byte) => byte.toString(16).padStart(2, "0"))
|
||||||
.join('');
|
.join("");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Icon components for better visual feedback
|
// Icon components for better visual feedback
|
||||||
const CheckIcon = () => (
|
const CheckIcon = () => (
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" className={styles.iconGreen} fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<svg
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
className={styles.iconGreen}
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth={2}
|
||||||
|
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
|
||||||
const XCircleIcon = () => (
|
const XCircleIcon = () => (
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" className={styles.iconRed} fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<svg
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
className={styles.iconRed}
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth={2}
|
||||||
|
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -46,7 +69,7 @@ export default function App() {
|
|||||||
// State for the nonce, which is the variable we can change
|
// State for the nonce, which is the variable we can change
|
||||||
const [nonce, setNonce] = useState(0);
|
const [nonce, setNonce] = useState(0);
|
||||||
// State to store the resulting hash
|
// 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
|
// A flag to indicate if the current hash is the "winning" one
|
||||||
const [isMining, setIsMining] = useState(false);
|
const [isMining, setIsMining] = useState(false);
|
||||||
const [isFound, setIsFound] = useState(false);
|
const [isFound, setIsFound] = useState(false);
|
||||||
@@ -55,7 +78,10 @@ export default function App() {
|
|||||||
const difficulty = "00";
|
const difficulty = "00";
|
||||||
|
|
||||||
// Memoize the combined data to avoid recalculating on every render
|
// 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.
|
// This effect hook recalculates the hash whenever the combinedData changes.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -68,7 +94,9 @@ export default function App() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
calculateHash();
|
calculateHash();
|
||||||
return () => { isMounted = false; };
|
return () => {
|
||||||
|
isMounted = false;
|
||||||
|
};
|
||||||
}, [combinedData, difficulty]);
|
}, [combinedData, difficulty]);
|
||||||
|
|
||||||
// This effect handles the automatic mining process
|
// This effect handles the automatic mining process
|
||||||
@@ -93,7 +121,7 @@ export default function App() {
|
|||||||
// Update the UI periodically to avoid freezing the browser
|
// Update the UI periodically to avoid freezing the browser
|
||||||
if (miningNonce % 100 === 0) {
|
if (miningNonce % 100 === 0) {
|
||||||
setNonce(miningNonce);
|
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 () => {
|
return () => {
|
||||||
continueMining = false;
|
continueMining = false;
|
||||||
}
|
};
|
||||||
}, [isMining, challenge, nonce, difficulty]);
|
}, [isMining, challenge, nonce, difficulty]);
|
||||||
|
|
||||||
|
|
||||||
const handleMineClick = () => {
|
const handleMineClick = () => {
|
||||||
setIsMining(true);
|
setIsMining(true);
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleStopClick = () => {
|
const handleStopClick = () => {
|
||||||
setIsMining(false);
|
setIsMining(false);
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleResetClick = () => {
|
const handleResetClick = () => {
|
||||||
setIsMining(false);
|
setIsMining(false);
|
||||||
setNonce(0);
|
setNonce(0);
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleNewChallengeClick = () => {
|
const handleNewChallengeClick = () => {
|
||||||
setIsMining(false);
|
setIsMining(false);
|
||||||
setChallenge(generateRandomHex(16));
|
setChallenge(generateRandomHex(16));
|
||||||
setNonce(0);
|
setNonce(0);
|
||||||
}
|
};
|
||||||
|
|
||||||
// Helper to render the hash with colored leading characters
|
// Helper to render the hash with colored leading characters
|
||||||
const renderHash = () => {
|
const renderHash = () => {
|
||||||
@@ -153,12 +180,46 @@ export default function App() {
|
|||||||
<div className={styles.block}>
|
<div className={styles.block}>
|
||||||
<h2 className={styles.blockTitle}>2. Nonce</h2>
|
<h2 className={styles.blockTitle}>2. Nonce</h2>
|
||||||
<div className={styles.nonceControls}>
|
<div className={styles.nonceControls}>
|
||||||
<button onClick={() => setNonce(n => n - 1)} disabled={isMining} className={styles.nonceButton}>
|
<button
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" className={styles.iconSmall} fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M20 12H4" /></svg>
|
onClick={() => setNonce((n) => n - 1)}
|
||||||
|
disabled={isMining}
|
||||||
|
className={styles.nonceButton}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
className={styles.iconSmall}
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth={2}
|
||||||
|
d="M20 12H4"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<span className={styles.nonceValue}>{nonce}</span>
|
<span className={styles.nonceValue}>{nonce}</span>
|
||||||
<button onClick={() => setNonce(n => n + 1)} disabled={isMining} className={styles.nonceButton}>
|
<button
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" className={styles.iconSmall} fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" /></svg>
|
onClick={() => setNonce((n) => n + 1)}
|
||||||
|
disabled={isMining}
|
||||||
|
className={styles.nonceButton}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
className={styles.iconSmall}
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth={2}
|
||||||
|
d="M12 4v16m8-8H4"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -172,13 +233,26 @@ export default function App() {
|
|||||||
|
|
||||||
{/* Arrow pointing down */}
|
{/* Arrow pointing down */}
|
||||||
<div className={styles.arrowContainer}>
|
<div className={styles.arrowContainer}>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" className={styles.iconGray} fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<svg
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 14l-7 7m0 0l-7-7m7 7V3" />
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
className={styles.iconGray}
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth={2}
|
||||||
|
d="M19 14l-7 7m0 0l-7-7m7 7V3"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Hash Output Block */}
|
{/* Hash Output Block */}
|
||||||
<div className={`${styles.hashContainer} ${isFound ? styles.hashContainerSuccess : styles.hashContainerError}`}>
|
<div
|
||||||
|
className={`${styles.hashContainer} ${isFound ? styles.hashContainerSuccess : styles.hashContainerError}`}
|
||||||
|
>
|
||||||
<div className={styles.hashContent}>
|
<div className={styles.hashContent}>
|
||||||
<div className={styles.hashText}>
|
<div className={styles.hashText}>
|
||||||
<h2 className={styles.blockTitle}>4. Resulting Hash (SHA-256)</h2>
|
<h2 className={styles.blockTitle}>4. Resulting Hash (SHA-256)</h2>
|
||||||
@@ -193,18 +267,30 @@ export default function App() {
|
|||||||
{/* Mining Controls */}
|
{/* Mining Controls */}
|
||||||
<div className={styles.buttonContainer}>
|
<div className={styles.buttonContainer}>
|
||||||
{!isMining ? (
|
{!isMining ? (
|
||||||
<button onClick={handleMineClick} className={`${styles.button} ${styles.buttonCyan}`}>
|
<button
|
||||||
|
onClick={handleMineClick}
|
||||||
|
className={`${styles.button} ${styles.buttonCyan}`}
|
||||||
|
>
|
||||||
Auto-Mine
|
Auto-Mine
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<button onClick={handleStopClick} className={`${styles.button} ${styles.buttonYellow}`}>
|
<button
|
||||||
|
onClick={handleStopClick}
|
||||||
|
className={`${styles.button} ${styles.buttonYellow}`}
|
||||||
|
>
|
||||||
Stop Mining
|
Stop Mining
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
<button onClick={handleNewChallengeClick} className={`${styles.button} ${styles.buttonIndigo}`}>
|
<button
|
||||||
|
onClick={handleNewChallengeClick}
|
||||||
|
className={`${styles.button} ${styles.buttonIndigo}`}
|
||||||
|
>
|
||||||
New Challenge
|
New Challenge
|
||||||
</button>
|
</button>
|
||||||
<button onClick={handleResetClick} className={`${styles.button} ${styles.buttonGray}`}>
|
<button
|
||||||
|
onClick={handleResetClick}
|
||||||
|
className={`${styles.button} ${styles.buttonGray}`}
|
||||||
|
>
|
||||||
Reset Nonce
|
Reset Nonce
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -48,7 +48,9 @@
|
|||||||
background-color: rgb(31 41 55);
|
background-color: rgb(31 41 55);
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
border-radius: 0.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%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -158,7 +160,9 @@
|
|||||||
.hashContainer {
|
.hashContainer {
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
border-radius: 0.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;
|
transition: all 300ms;
|
||||||
border: 2px solid;
|
border: 2px solid;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ 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`.
|
`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 |
|
| Input | Output |
|
||||||
| :------------------------ | :------------------------------ |
|
| :------------------------- | :-------------- |
|
||||||
| `regexSafe("1.2.3.4")` | `1\\.2\\.3\\.4` |
|
| `regexSafe("1.2.3.4")` | `1\\.2\\.3\\.4` |
|
||||||
| `regexSafe("techaro.lol")` | `techaro\\.lol` |
|
| `regexSafe("techaro.lol")` | `techaro\\.lol` |
|
||||||
| `regexSafe("star*")` | `star\\*` |
|
| `regexSafe("star*")` | `star\\*` |
|
||||||
@@ -302,7 +302,7 @@ 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.
|
`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 |
|
| Input | Output |
|
||||||
| :----------------------------- | :------------------------------------------------------------------- |
|
| :----------------------------- | :---------------------------------------------------------------- |
|
||||||
| `arpaReverseIP("1.2.3.4")` | `4.3.2.1` |
|
| `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` |
|
| `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` |
|
||||||
|
|
||||||
|
|||||||
@@ -94,10 +94,8 @@ containers:
|
|||||||
- ALL
|
- ALL
|
||||||
seccompProfile:
|
seccompProfile:
|
||||||
type: RuntimeDefault
|
type: RuntimeDefault
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
Then add a Service entry for Anubis:
|
Then add a Service entry for Anubis:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
|||||||
@@ -1,8 +1,2 @@
|
|||||||
# /etc/nginx/conf-anubis.inc
|
# /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; }
|
||||||
# Forward to anubis
|
|
||||||
location / {
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_pass http://anubis;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ services:
|
|||||||
# Telling Anubis, where to listen for Traefik
|
# Telling Anubis, where to listen for Traefik
|
||||||
- BIND=:8080
|
- BIND=:8080
|
||||||
# Telling Anubis to do redirect — ensure there is a space after '='
|
# Telling Anubis to do redirect — ensure there is a space after '='
|
||||||
- 'TARGET= '
|
- "TARGET= "
|
||||||
# Specifies which domains Anubis is allowed to redirect to.
|
# Specifies which domains Anubis is allowed to redirect to.
|
||||||
- REDIRECT_DOMAINS=example.com
|
- REDIRECT_DOMAINS=example.com
|
||||||
# Should be the full external URL for Anubis (including scheme)
|
# Should be the full external URL for Anubis (including scheme)
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ Currently the following settings are configurable via the policy file:
|
|||||||
Anubis uses these environment variables for configuration:
|
Anubis uses these environment variables for configuration:
|
||||||
|
|
||||||
| Environment Variable | Default value | Explanation |
|
| Environment Variable | Default value | Explanation |
|
||||||
|:-------------------------------|:------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
| :----------------------------- | :---------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `ASSET_LOOKUP_HEADER` | unset | <EO /> 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. |
|
| `ASSET_LOOKUP_HEADER` | unset | <EO /> 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. |
|
| `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` |
|
| `BIND` | `:8923` | The network address that Anubis listens on. For `unix`, set this to a path: `/run/anubis/instance.sock` |
|
||||||
|
|||||||
+61
-61
@@ -1,62 +1,62 @@
|
|||||||
import { themes as prismThemes } from 'prism-react-renderer';
|
import { themes as prismThemes } from "prism-react-renderer";
|
||||||
import type { Config } from '@docusaurus/types';
|
import type { Config } from "@docusaurus/types";
|
||||||
import type * as Preset from '@docusaurus/preset-classic';
|
import type * as Preset from "@docusaurus/preset-classic";
|
||||||
|
|
||||||
// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...)
|
// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...)
|
||||||
|
|
||||||
const config: Config = {
|
const config: Config = {
|
||||||
title: 'Anubis',
|
title: "Anubis",
|
||||||
tagline: 'Weigh the soul of incoming HTTP requests to protect your website!',
|
tagline: "Weigh the soul of incoming HTTP requests to protect your website!",
|
||||||
favicon: 'img/favicon.ico',
|
favicon: "img/favicon.ico",
|
||||||
|
|
||||||
// Set the production url of your site here
|
// Set the production url of your site here
|
||||||
url: 'https://anubis.techaro.lol',
|
url: "https://anubis.techaro.lol",
|
||||||
// Set the /<baseUrl>/ pathname under which your site is served
|
// Set the /<baseUrl>/ pathname under which your site is served
|
||||||
// For GitHub pages deployment, it is often '/<projectName>/'
|
// For GitHub pages deployment, it is often '/<projectName>/'
|
||||||
baseUrl: '/',
|
baseUrl: "/",
|
||||||
|
|
||||||
// GitHub pages deployment config.
|
// GitHub pages deployment config.
|
||||||
// If you aren't using GitHub pages, you don't need these.
|
// If you aren't using GitHub pages, you don't need these.
|
||||||
organizationName: 'TecharoHQ', // Usually your GitHub org/user name.
|
organizationName: "TecharoHQ", // Usually your GitHub org/user name.
|
||||||
projectName: 'anubis', // Usually your repo name.
|
projectName: "anubis", // Usually your repo name.
|
||||||
|
|
||||||
onBrokenLinks: 'throw',
|
onBrokenLinks: "throw",
|
||||||
onBrokenMarkdownLinks: 'warn',
|
onBrokenMarkdownLinks: "warn",
|
||||||
|
|
||||||
// Even if you don't use internationalization, you can use this field to set
|
// 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
|
// useful metadata like html lang. For example, if your site is Chinese, you
|
||||||
// may want to replace "en" with "zh-Hans".
|
// may want to replace "en" with "zh-Hans".
|
||||||
i18n: {
|
i18n: {
|
||||||
defaultLocale: 'en',
|
defaultLocale: "en",
|
||||||
locales: ['en'],
|
locales: ["en"],
|
||||||
},
|
},
|
||||||
|
|
||||||
markdown: {
|
markdown: {
|
||||||
mermaid: true,
|
mermaid: true,
|
||||||
},
|
},
|
||||||
themes: ['@docusaurus/theme-mermaid'],
|
themes: ["@docusaurus/theme-mermaid"],
|
||||||
|
|
||||||
presets: [
|
presets: [
|
||||||
[
|
[
|
||||||
'classic',
|
"classic",
|
||||||
{
|
{
|
||||||
blog: {
|
blog: {
|
||||||
showReadingTime: true,
|
showReadingTime: true,
|
||||||
feedOptions: {
|
feedOptions: {
|
||||||
type: ['rss', 'atom', "json"],
|
type: ["rss", "atom", "json"],
|
||||||
xslt: true,
|
xslt: true,
|
||||||
},
|
},
|
||||||
editUrl: 'https://github.com/TecharoHQ/anubis/tree/main/docs/',
|
editUrl: "https://github.com/TecharoHQ/anubis/tree/main/docs/",
|
||||||
onInlineTags: 'warn',
|
onInlineTags: "warn",
|
||||||
onInlineAuthors: 'warn',
|
onInlineAuthors: "warn",
|
||||||
onUntruncatedBlogPosts: 'throw',
|
onUntruncatedBlogPosts: "throw",
|
||||||
},
|
},
|
||||||
docs: {
|
docs: {
|
||||||
sidebarPath: './sidebars.ts',
|
sidebarPath: "./sidebars.ts",
|
||||||
editUrl: 'https://github.com/TecharoHQ/anubis/tree/main/docs/',
|
editUrl: "https://github.com/TecharoHQ/anubis/tree/main/docs/",
|
||||||
},
|
},
|
||||||
theme: {
|
theme: {
|
||||||
customCss: './src/css/custom.css',
|
customCss: "./src/css/custom.css",
|
||||||
},
|
},
|
||||||
} satisfies Preset.Options,
|
} satisfies Preset.Options,
|
||||||
],
|
],
|
||||||
@@ -67,47 +67,47 @@ const config: Config = {
|
|||||||
respectPrefersColorScheme: true,
|
respectPrefersColorScheme: true,
|
||||||
},
|
},
|
||||||
// Replace with your project's social card
|
// Replace with your project's social card
|
||||||
image: 'img/social-card.jpg',
|
image: "img/social-card.jpg",
|
||||||
navbar: {
|
navbar: {
|
||||||
title: 'Anubis',
|
title: "Anubis",
|
||||||
logo: {
|
logo: {
|
||||||
alt: 'A happy jackal woman with brown hair and red eyes',
|
alt: "A happy jackal woman with brown hair and red eyes",
|
||||||
src: 'img/favicon.webp',
|
src: "img/favicon.webp",
|
||||||
},
|
},
|
||||||
items: [
|
items: [
|
||||||
{ to: '/blog', label: 'Blog', position: 'left' },
|
{ to: "/blog", label: "Blog", position: "left" },
|
||||||
{
|
{
|
||||||
type: 'docSidebar',
|
type: "docSidebar",
|
||||||
sidebarId: 'tutorialSidebar',
|
sidebarId: "tutorialSidebar",
|
||||||
position: 'left',
|
position: "left",
|
||||||
label: 'Docs',
|
label: "Docs",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: '/docs/admin/botstopper',
|
to: "/docs/admin/botstopper",
|
||||||
label: "Unbranded Version",
|
label: "Unbranded Version",
|
||||||
position: "left"
|
position: "left",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
href: 'https://github.com/TecharoHQ/anubis',
|
href: "https://github.com/TecharoHQ/anubis",
|
||||||
label: 'GitHub',
|
label: "GitHub",
|
||||||
position: 'right',
|
position: "right",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
href: 'https://github.com/sponsors/Xe',
|
href: "https://github.com/sponsors/Xe",
|
||||||
label: "Sponsor the Project",
|
label: "Sponsor the Project",
|
||||||
position: 'right'
|
position: "right",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
footer: {
|
footer: {
|
||||||
style: 'dark',
|
style: "dark",
|
||||||
links: [
|
links: [
|
||||||
{
|
{
|
||||||
title: 'Docs',
|
title: "Docs",
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
label: 'Intro',
|
label: "Intro",
|
||||||
to: '/docs/',
|
to: "/docs/",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Installation",
|
label: "Installation",
|
||||||
@@ -116,32 +116,32 @@ const config: Config = {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Community',
|
title: "Community",
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
label: 'GitHub Discussions',
|
label: "GitHub Discussions",
|
||||||
href: 'https://github.com/TecharoHQ/anubis/discussions',
|
href: "https://github.com/TecharoHQ/anubis/discussions",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Bluesky',
|
label: "Bluesky",
|
||||||
href: 'https://bsky.app/profile/techaro.lol',
|
href: "https://bsky.app/profile/techaro.lol",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'More',
|
title: "More",
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
label: 'Blog',
|
label: "Blog",
|
||||||
to: '/blog',
|
to: "/blog",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'GitHub',
|
label: "GitHub",
|
||||||
href: 'https://github.com/TecharoHQ/anubis',
|
href: "https://github.com/TecharoHQ/anubis",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Status',
|
label: "Status",
|
||||||
href: 'https://techarohq.github.io/status/'
|
href: "https://techarohq.github.io/status/",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -153,13 +153,13 @@ const config: Config = {
|
|||||||
darkTheme: prismThemes.dracula,
|
darkTheme: prismThemes.dracula,
|
||||||
magicComments: [
|
magicComments: [
|
||||||
{
|
{
|
||||||
className: 'code-block-diff-add-line',
|
className: "code-block-diff-add-line",
|
||||||
line: 'diff-add'
|
line: "diff-add",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
className: 'code-block-diff-remove-line',
|
className: "code-block-diff-remove-line",
|
||||||
line: 'diff-remove'
|
line: "diff-remove",
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
} satisfies Preset.ThemeConfig,
|
} satisfies Preset.ThemeConfig,
|
||||||
|
|||||||
+2
-2
@@ -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...)
|
// 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 = {
|
const sidebars: SidebarsConfig = {
|
||||||
// By default, Docusaurus generates a sidebar from the docs folder structure
|
// 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
|
// But you can create a sidebar manually
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import styles from './styles.module.css';
|
import styles from "./styles.module.css";
|
||||||
|
|
||||||
export default function EnterpriseOnly({ link }) {
|
export default function EnterpriseOnly({ link }) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -8,7 +8,9 @@
|
|||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
padding: 0.5rem 1rem; /* py-2 px-4 */
|
padding: 0.5rem 1rem; /* py-2 px-4 */
|
||||||
border-radius: 9999px; /* rounded-full */
|
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 */
|
display: inline-flex; /* flex */
|
||||||
align-items: center; /* items-center */
|
align-items: center; /* items-center */
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,9 @@
|
|||||||
*/
|
*/
|
||||||
const h = (name, data = {}, children = []) => {
|
const h = (name, data = {}, children = []) => {
|
||||||
const result =
|
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)) {
|
if (!Array.isArray(children)) {
|
||||||
children = [children];
|
children = [children];
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-3
@@ -1,5 +1,3 @@
|
|||||||
{
|
{
|
||||||
"bots": [
|
"bots": [{}]
|
||||||
{}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
+1
-3
@@ -8,9 +8,7 @@
|
|||||||
"userAgent.startsWith(\"git/\") || userAgent.contains(\"libgit\")",
|
"userAgent.startsWith(\"git/\") || userAgent.contains(\"libgit\")",
|
||||||
"\"Git-Protocol\" in headers && headers[\"Git-Protocol\"] == \"version=2\"\n"
|
"\"Git-Protocol\" in headers && headers[\"Git-Protocol\"] == \"version=2\"\n"
|
||||||
],
|
],
|
||||||
"any": [
|
"any": ["userAgent.startsWith(\"evilbot/\")"]
|
||||||
"userAgent.startsWith(\"evilbot/\")"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
+1
-4
@@ -2,10 +2,7 @@
|
|||||||
"bots": [
|
"bots": [
|
||||||
{
|
{
|
||||||
"name": "everyones-invited",
|
"name": "everyones-invited",
|
||||||
"remote_addresses": [
|
"remote_addresses": ["0.0.0.0/0", "::/0"],
|
||||||
"0.0.0.0/0",
|
|
||||||
"::/0"
|
|
||||||
],
|
|
||||||
"action": "ALLOW"
|
"action": "ALLOW"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
Vendored
+1
-3
@@ -2,8 +2,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ipv6-ula",
|
"name": "ipv6-ula",
|
||||||
"action": "ALLOW",
|
"action": "ALLOW",
|
||||||
"remote_addresses": [
|
"remote_addresses": ["fc00::/7"]
|
||||||
"fc00::/7"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
Vendored
+1
-3
@@ -2,8 +2,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ipv6-ula",
|
"name": "ipv6-ula",
|
||||||
"action": "ALLOW",
|
"action": "ALLOW",
|
||||||
"remote_addresses": [
|
"remote_addresses": ["fc00::/7"]
|
||||||
"fc00::/7"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
Vendored
+1
-3
@@ -2,8 +2,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ipv6-ula",
|
"name": "ipv6-ula",
|
||||||
"action": "ALLOW",
|
"action": "ALLOW",
|
||||||
"remote_addresses": [
|
"remote_addresses": ["fc00::/7"]
|
||||||
"fc00::/7"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
+4
-2
@@ -12,8 +12,10 @@
|
|||||||
"build": "npm run assets && go build -o ./var/anubis ./cmd/anubis",
|
"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",
|
"dev": "npm run assets && go run ./cmd/anubis --use-remote-address --target http://localhost:3000",
|
||||||
"container": "npm run assets && go run ./cmd/containerbuild",
|
"container": "npm run assets && go run ./cmd/containerbuild",
|
||||||
"package": "yeet",
|
"package": "go tool yeet",
|
||||||
"lint": "make lint"
|
"lint": "make lint",
|
||||||
|
"prepare": "go mod download",
|
||||||
|
"format": "prettier -w . 2>&1 >/dev/null"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ import { createInterface } from "readline";
|
|||||||
|
|
||||||
async function getPage(path) {
|
async function getPage(path) {
|
||||||
return fetch(`http://localhost:8923${path}`)
|
return fetch(`http://localhost:8923${path}`)
|
||||||
.then(resp => {
|
.then((resp) => {
|
||||||
if (resp.status !== 200) {
|
if (resp.status !== 200) {
|
||||||
throw new Error(`wanted status 200, got status: ${resp.status}`);
|
throw new Error(`wanted status 200, got status: ${resp.status}`);
|
||||||
}
|
}
|
||||||
return resp;
|
return resp;
|
||||||
})
|
})
|
||||||
.then(resp => resp.text());
|
.then((resp) => resp.text());
|
||||||
}
|
}
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
|
|||||||
@@ -3,22 +3,22 @@ async function getChallengePage() {
|
|||||||
headers: {
|
headers: {
|
||||||
"Accept-Language": "en",
|
"Accept-Language": "en",
|
||||||
"User-Agent": "CHALLENGE",
|
"User-Agent": "CHALLENGE",
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.then(resp => {
|
.then((resp) => {
|
||||||
if (resp.status !== 200) {
|
if (resp.status !== 200) {
|
||||||
throw new Error(`wanted status 200, got status: ${resp.status}`);
|
throw new Error(`wanted status 200, got status: ${resp.status}`);
|
||||||
}
|
}
|
||||||
return resp;
|
return resp;
|
||||||
})
|
})
|
||||||
.then(resp => resp.text());
|
.then((resp) => resp.text());
|
||||||
}
|
}
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
const page = await getChallengePage();
|
const page = await getChallengePage();
|
||||||
|
|
||||||
if (!page.includes(`<html lang="de">`)) {
|
if (!page.includes(`<html lang="de">`)) {
|
||||||
console.log(page)
|
console.log(page);
|
||||||
throw new Error("force language smoke test failed");
|
throw new Error("force language smoke test failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+9
-7
@@ -1,12 +1,14 @@
|
|||||||
async function fetchLanguages() {
|
async function fetchLanguages() {
|
||||||
return fetch("http://localhost:8923/.within.website/x/cmd/anubis/static/locales/manifest.json")
|
return fetch(
|
||||||
.then(resp => {
|
"http://localhost:8923/.within.website/x/cmd/anubis/static/locales/manifest.json",
|
||||||
|
)
|
||||||
|
.then((resp) => {
|
||||||
if (resp.status !== 200) {
|
if (resp.status !== 200) {
|
||||||
throw new Error(`wanted status 200, got status: ${resp.status}`);
|
throw new Error(`wanted status 200, got status: ${resp.status}`);
|
||||||
}
|
}
|
||||||
return resp;
|
return resp;
|
||||||
})
|
})
|
||||||
.then(resp => resp.json());
|
.then((resp) => resp.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getChallengePage(lang) {
|
async function getChallengePage(lang) {
|
||||||
@@ -14,15 +16,15 @@ async function getChallengePage(lang) {
|
|||||||
headers: {
|
headers: {
|
||||||
"Accept-Language": lang,
|
"Accept-Language": lang,
|
||||||
"User-Agent": "CHALLENGE",
|
"User-Agent": "CHALLENGE",
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.then(resp => {
|
.then((resp) => {
|
||||||
if (resp.status !== 200) {
|
if (resp.status !== 200) {
|
||||||
throw new Error(`wanted status 200, got status: ${resp.status}`);
|
throw new Error(`wanted status 200, got status: ${resp.status}`);
|
||||||
}
|
}
|
||||||
return resp;
|
return resp;
|
||||||
})
|
})
|
||||||
.then(resp => resp.text());
|
.then((resp) => resp.text());
|
||||||
}
|
}
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
@@ -42,7 +44,7 @@ async function getChallengePage(lang) {
|
|||||||
console.log(`getting for ${lang}`);
|
console.log(`getting for ${lang}`);
|
||||||
const page = await getChallengePage(lang);
|
const page = await getChallengePage(lang);
|
||||||
|
|
||||||
resultSheet[lang] = page.includes(`<html lang="${lang}">`)
|
resultSheet[lang] = page.includes(`<html lang="${lang}">`);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const [lang, result] of Object.entries(resultSheet)) {
|
for (const [lang, result] of Object.entries(resultSheet)) {
|
||||||
|
|||||||
+13
-7
@@ -3,16 +3,16 @@ import { statSync } from "fs";
|
|||||||
async function getPage(path) {
|
async function getPage(path) {
|
||||||
return fetch(`http://localhost:8923${path}`, {
|
return fetch(`http://localhost:8923${path}`, {
|
||||||
headers: {
|
headers: {
|
||||||
'User-Agent': 'CHALLENGE'
|
"User-Agent": "CHALLENGE",
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.then(resp => {
|
.then((resp) => {
|
||||||
if (resp.status !== 200) {
|
if (resp.status !== 200) {
|
||||||
throw new Error(`wanted status 200, got status: ${resp.status}`);
|
throw new Error(`wanted status 200, got status: ${resp.status}`);
|
||||||
}
|
}
|
||||||
return resp;
|
return resp;
|
||||||
})
|
})
|
||||||
.then(resp => resp.text());
|
.then((resp) => resp.text());
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getFileSize(filePath) {
|
async function getFileSize(filePath) {
|
||||||
@@ -63,7 +63,9 @@ async function getFileSize(filePath) {
|
|||||||
|
|
||||||
// Verify that log file size increased
|
// Verify that log file size increased
|
||||||
if (finalSize <= initialSize) {
|
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;
|
failed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,10 +81,14 @@ async function getFileSize(filePath) {
|
|||||||
console.log(`Successful requests: ${successCount}/${requests.length}`);
|
console.log(`Successful requests: ${successCount}/${requests.length}`);
|
||||||
|
|
||||||
if (failed) {
|
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);
|
process.exit(1);
|
||||||
} else {
|
} 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);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
@@ -1,8 +1,2 @@
|
|||||||
# /etc/nginx/conf-anubis.inc
|
# /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; }
|
||||||
# Forward to anubis
|
|
||||||
location / {
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_pass http://anubis;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,22 +3,22 @@ async function getRobotsTxt() {
|
|||||||
headers: {
|
headers: {
|
||||||
"Accept-Language": "en",
|
"Accept-Language": "en",
|
||||||
"User-Agent": "Mozilla/5.0",
|
"User-Agent": "Mozilla/5.0",
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
.then(resp => {
|
.then((resp) => {
|
||||||
if (resp.status !== 200) {
|
if (resp.status !== 200) {
|
||||||
throw new Error(`wanted status 200, got status: ${resp.status}`);
|
throw new Error(`wanted status 200, got status: ${resp.status}`);
|
||||||
}
|
}
|
||||||
return resp;
|
return resp;
|
||||||
})
|
})
|
||||||
.then(resp => resp.text());
|
.then((resp) => resp.text());
|
||||||
}
|
}
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
const page = await getRobotsTxt();
|
const page = await getRobotsTxt();
|
||||||
|
|
||||||
if (page.includes(`<html>`)) {
|
if (page.includes(`<html>`)) {
|
||||||
console.log(page)
|
console.log(page);
|
||||||
throw new Error("serve robots.txt smoke test failed");
|
throw new Error("serve robots.txt smoke test failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Anubis works!</title>
|
<title>Anubis works!</title>
|
||||||
@@ -11,7 +11,10 @@
|
|||||||
|
|
||||||
<p>If you see this, everything has gone according to keikaku.</p>
|
<p>If you see this, everything has gone according to keikaku.</p>
|
||||||
|
|
||||||
<img height=128 src="/.within.website/x/cmd/anubis/static/img/happy.webp"/>
|
<img
|
||||||
|
height="128"
|
||||||
|
src="/.within.website/x/cmd/anubis/static/img/happy.webp"
|
||||||
|
/>
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -1,19 +1,20 @@
|
|||||||
async function testWithUserAgent(userAgent) {
|
async function testWithUserAgent(userAgent) {
|
||||||
const statusCode =
|
const statusCode = await fetch(
|
||||||
await fetch("https://relayd.local.cetacean.club:3004/reqmeta", {
|
"https://relayd.local.cetacean.club:3004/reqmeta",
|
||||||
|
{
|
||||||
headers: {
|
headers: {
|
||||||
"User-Agent": userAgent,
|
"User-Agent": userAgent,
|
||||||
}
|
},
|
||||||
})
|
},
|
||||||
.then(resp => resp.status);
|
).then((resp) => resp.status);
|
||||||
return statusCode;
|
return statusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const codes = {
|
const codes = {
|
||||||
allow: await testWithUserAgent("ALLOW"),
|
allow: await testWithUserAgent("ALLOW"),
|
||||||
challenge: await testWithUserAgent("CHALLENGE"),
|
challenge: await testWithUserAgent("CHALLENGE"),
|
||||||
deny: await testWithUserAgent("DENY")
|
deny: await testWithUserAgent("DENY"),
|
||||||
}
|
};
|
||||||
|
|
||||||
const expected = {
|
const expected = {
|
||||||
allow: 200,
|
allow: 200,
|
||||||
@@ -26,5 +27,7 @@ console.log("CHALLENGE:", codes.challenge);
|
|||||||
console.log("DENY: ", codes.deny);
|
console.log("DENY: ", codes.deny);
|
||||||
|
|
||||||
if (JSON.stringify(codes) !== JSON.stringify(expected)) {
|
if (JSON.stringify(codes) !== JSON.stringify(expected)) {
|
||||||
throw new Error(`wanted ${JSON.stringify(expected)}, got: ${JSON.stringify(codes)}`);
|
throw new Error(
|
||||||
|
`wanted ${JSON.stringify(expected)}, got: ${JSON.stringify(codes)}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,9 @@ interface ProcessOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const getHardwareConcurrency = () =>
|
const getHardwareConcurrency = () =>
|
||||||
navigator.hardwareConcurrency !== undefined ? navigator.hardwareConcurrency : 1;
|
navigator.hardwareConcurrency !== undefined
|
||||||
|
? navigator.hardwareConcurrency
|
||||||
|
: 1;
|
||||||
|
|
||||||
export default function process(
|
export default function process(
|
||||||
options: ProcessOptions,
|
options: ProcessOptions,
|
||||||
@@ -25,7 +27,10 @@ export default function process(
|
|||||||
workerMethod = "webcrypto";
|
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");
|
console.log("Firefox detected, using pure-JS fallback");
|
||||||
workerMethod = "purejs";
|
workerMethod = "purejs";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ import fast from "./fast";
|
|||||||
export default {
|
export default {
|
||||||
fast: fast,
|
fast: fast,
|
||||||
slow: fast, // XXX(Xe): slow is deprecated, but keep this around in case anything goes bad
|
slow: fast, // XXX(Xe): slow is deprecated, but keep this around in case anything goes bad
|
||||||
}
|
};
|
||||||
|
|||||||
+27
-8
@@ -2,13 +2,27 @@ import algorithms from "./algorithms";
|
|||||||
|
|
||||||
const defaultDifficulty = 4;
|
const defaultDifficulty = 4;
|
||||||
|
|
||||||
const status: HTMLParagraphElement = document.getElementById("status") as HTMLParagraphElement;
|
const status: HTMLParagraphElement = document.getElementById(
|
||||||
const difficultyInput: HTMLInputElement = document.getElementById("difficulty-input") as HTMLInputElement;
|
"status",
|
||||||
const algorithmSelect: HTMLSelectElement = document.getElementById("algorithm-select") as HTMLSelectElement;
|
) as HTMLParagraphElement;
|
||||||
const compareSelect: HTMLSelectElement = document.getElementById("compare-select") as HTMLSelectElement;
|
const difficultyInput: HTMLInputElement = document.getElementById(
|
||||||
const header: HTMLTableRowElement = document.getElementById("table-header") as HTMLTableRowElement;
|
"difficulty-input",
|
||||||
const headerCompare: HTMLTableSectionElement = document.getElementById("table-header-compare") as HTMLTableSectionElement;
|
) as HTMLInputElement;
|
||||||
const results: HTMLTableRowElement = document.getElementById("results") as HTMLTableRowElement;
|
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 = () => {
|
const setupControls = () => {
|
||||||
if (defaultDifficulty == null) {
|
if (defaultDifficulty == null) {
|
||||||
@@ -41,7 +55,12 @@ const benchmarkTrial = async (stats, difficulty, algorithm, signal) => {
|
|||||||
.join("");
|
.join("");
|
||||||
|
|
||||||
const t0 = performance.now();
|
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();
|
const t1 = performance.now();
|
||||||
console.log({ hash, nonce });
|
console.log({ hash, nonce });
|
||||||
|
|
||||||
|
|||||||
+49
-31
@@ -29,22 +29,25 @@ const getAvailableLanguages = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
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) {
|
if (response.ok) {
|
||||||
const manifest = await response.json();
|
const manifest = await response.json();
|
||||||
return manifest.supportedLanguages || ['en'];
|
return manifest.supportedLanguages || ["en"];
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} 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
|
// 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
|
// Use the browser language from the HTML lang attribute which is set by the server settings or request headers
|
||||||
const getBrowserLanguage = async () =>
|
const getBrowserLanguage = async () => document.documentElement.lang;
|
||||||
document.documentElement.lang;
|
|
||||||
|
|
||||||
// Load translations from JSON files
|
// Load translations from JSON files
|
||||||
const loadTranslations = async (lang) => {
|
const loadTranslations = async (lang) => {
|
||||||
@@ -54,12 +57,16 @@ const loadTranslations = async (lang) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
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();
|
return await response.json();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(`Failed to load translations for ${lang}, falling back to English`);
|
console.warn(
|
||||||
if (lang !== 'en') {
|
`Failed to load translations for ${lang}, falling back to English`,
|
||||||
return await loadTranslations('en');
|
);
|
||||||
|
if (lang !== "en") {
|
||||||
|
return await loadTranslations("en");
|
||||||
}
|
}
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
@@ -72,10 +79,10 @@ const getRedirectUrl = () => {
|
|||||||
}
|
}
|
||||||
if (publicUrl && window.location.href.startsWith(publicUrl)) {
|
if (publicUrl && window.location.href.startsWith(publicUrl)) {
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
return urlParams.get('redir');
|
return urlParams.get("redir");
|
||||||
}
|
}
|
||||||
return window.location.href;
|
return window.location.href;
|
||||||
}
|
};
|
||||||
|
|
||||||
let translations = {};
|
let translations = {};
|
||||||
let currentLang;
|
let currentLang;
|
||||||
@@ -95,20 +102,28 @@ const t = (key) => translations[`js_${key}`] || translations[key] || key;
|
|||||||
const dependencies = [
|
const dependencies = [
|
||||||
{
|
{
|
||||||
name: "Web Workers",
|
name: "Web Workers",
|
||||||
msg: t('web_workers_error'),
|
msg: t("web_workers_error"),
|
||||||
value: window.Worker,
|
value: window.Worker,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Cookies",
|
name: "Cookies",
|
||||||
msg: t('cookies_error'),
|
msg: t("cookies_error"),
|
||||||
value: navigator.cookieEnabled,
|
value: navigator.cookieEnabled,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const status: HTMLParagraphElement = document.getElementById("status") as HTMLParagraphElement;
|
const status: HTMLParagraphElement = document.getElementById(
|
||||||
const image: HTMLImageElement = document.getElementById("image") as HTMLImageElement;
|
"status",
|
||||||
const title: HTMLHeadingElement = document.getElementById("title") as HTMLHeadingElement;
|
) as HTMLParagraphElement;
|
||||||
const progress: HTMLDivElement = document.getElementById("progress") as HTMLDivElement;
|
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 anubisVersion = j("anubis_version");
|
||||||
const basePrefix = j("anubis_base_prefix");
|
const basePrefix = j("anubis_base_prefix");
|
||||||
@@ -130,12 +145,12 @@ const t = (key) => translations[`js_${key}`] || translations[key] || key;
|
|||||||
progress.style.display = "none";
|
progress.style.display = "none";
|
||||||
};
|
};
|
||||||
|
|
||||||
status.innerHTML = t('calculating');
|
status.innerHTML = t("calculating");
|
||||||
|
|
||||||
for (const { value, name, msg } of dependencies) {
|
for (const { value, name, msg } of dependencies) {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
ohNoes({
|
ohNoes({
|
||||||
titleMsg: `${t('missing_feature')} ${name}`,
|
titleMsg: `${t("missing_feature")} ${name}`,
|
||||||
statusMsg: msg,
|
statusMsg: msg,
|
||||||
imageSrc: imageURL("reject", anubisVersion, basePrefix),
|
imageSrc: imageURL("reject", anubisVersion, basePrefix),
|
||||||
});
|
});
|
||||||
@@ -148,20 +163,20 @@ const t = (key) => translations[`js_${key}`] || translations[key] || key;
|
|||||||
const process = algorithms[rules.algorithm];
|
const process = algorithms[rules.algorithm];
|
||||||
if (!process) {
|
if (!process) {
|
||||||
ohNoes({
|
ohNoes({
|
||||||
titleMsg: t('challenge_error'),
|
titleMsg: t("challenge_error"),
|
||||||
statusMsg: t('challenge_error_msg'),
|
statusMsg: t("challenge_error_msg"),
|
||||||
imageSrc: imageURL("reject", anubisVersion, basePrefix),
|
imageSrc: imageURL("reject", anubisVersion, basePrefix),
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
status.innerHTML = `${t('calculating_difficulty')} ${rules.difficulty}, `;
|
status.innerHTML = `${t("calculating_difficulty")} ${rules.difficulty}, `;
|
||||||
progress.style.display = "inline-block";
|
progress.style.display = "inline-block";
|
||||||
|
|
||||||
// the whole text, including "Speed:", as a single node, because some browsers
|
// the whole text, including "Speed:", as a single node, because some browsers
|
||||||
// (Firefox mobile) present screen readers with each node as a separate piece
|
// (Firefox mobile) present screen readers with each node as a separate piece
|
||||||
// of text.
|
// of text.
|
||||||
const rateText = document.createTextNode(`${t('speed')} 0kH/s`);
|
const rateText = document.createTextNode(`${t("speed")} 0kH/s`);
|
||||||
status.appendChild(rateText);
|
status.appendChild(rateText);
|
||||||
|
|
||||||
let lastSpeedUpdate = 0;
|
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
|
// only update the speed every second so it's less visually distracting
|
||||||
if (delta - lastSpeedUpdate > 1000) {
|
if (delta - lastSpeedUpdate > 1000) {
|
||||||
lastSpeedUpdate = delta;
|
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.
|
// 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
|
// 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;
|
const distance = (1 - Math.pow(probability, 2)) * 100;
|
||||||
progress["aria-valuenow"] = distance;
|
progress["aria-valuenow"] = distance;
|
||||||
if (progress.firstElementChild !== null) {
|
if (progress.firstElementChild !== null) {
|
||||||
(progress.firstElementChild as HTMLElement).style.width = `${distance}%`;
|
(progress.firstElementChild as HTMLElement).style.width =
|
||||||
|
`${distance}%`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (probability < 0.1 && !showingApology) {
|
if (probability < 0.1 && !showingApology) {
|
||||||
status.append(
|
status.append(
|
||||||
document.createElement("br"),
|
document.createElement("br"),
|
||||||
document.createTextNode(t('verification_longer')),
|
document.createTextNode(t("verification_longer")),
|
||||||
);
|
);
|
||||||
showingApology = true;
|
showingApology = true;
|
||||||
}
|
}
|
||||||
@@ -208,7 +224,9 @@ const t = (key) => translations[`js_${key}`] || translations[key] || key;
|
|||||||
console.log({ hash, nonce });
|
console.log({ hash, nonce });
|
||||||
|
|
||||||
if (userReadDetails) {
|
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
|
// Style progress bar as a continue button
|
||||||
container.style.display = "flex";
|
container.style.display = "flex";
|
||||||
@@ -224,7 +242,7 @@ const t = (key) => translations[`js_${key}`] || translations[key] || key;
|
|||||||
container.style.outlineOffset = "2px";
|
container.style.outlineOffset = "2px";
|
||||||
container.style.width = "min(20rem, 90%)";
|
container.style.width = "min(20rem, 90%)";
|
||||||
container.style.margin = "1rem auto 2rem";
|
container.style.margin = "1rem auto 2rem";
|
||||||
container.innerHTML = t('finished_reading');
|
container.innerHTML = t("finished_reading");
|
||||||
|
|
||||||
function onDetailsExpand() {
|
function onDetailsExpand() {
|
||||||
const redir = getRedirectUrl();
|
const redir = getRedirectUrl();
|
||||||
@@ -255,8 +273,8 @@ const t = (key) => translations[`js_${key}`] || translations[key] || key;
|
|||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
ohNoes({
|
ohNoes({
|
||||||
titleMsg: t('calculation_error'),
|
titleMsg: t("calculation_error"),
|
||||||
statusMsg: `${t('calculation_error_msg')} ${err.message}`,
|
statusMsg: `${t("calculation_error_msg")} ${err.message}`,
|
||||||
imageSrc: imageURL("reject", anubisVersion, basePrefix),
|
imageSrc: imageURL("reject", anubisVersion, basePrefix),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Sha256 } from '@aws-crypto/sha256-js';
|
import { Sha256 } from "@aws-crypto/sha256-js";
|
||||||
|
|
||||||
const calculateSHA256 = (text) => {
|
const calculateSHA256 = (text) => {
|
||||||
const hash = new Sha256();
|
const hash = new Sha256();
|
||||||
@@ -12,7 +12,7 @@ function toHexString(arr: Uint8Array): string {
|
|||||||
.join("");
|
.join("");
|
||||||
}
|
}
|
||||||
|
|
||||||
addEventListener('message', async ({ data: eventData }) => {
|
addEventListener("message", async ({ data: eventData }) => {
|
||||||
const { data, difficulty, threads } = eventData;
|
const { data, difficulty, threads } = eventData;
|
||||||
let nonce = eventData.nonce;
|
let nonce = eventData.nonce;
|
||||||
const isMainThread = nonce === 0;
|
const isMainThread = nonce === 0;
|
||||||
@@ -34,7 +34,7 @@ addEventListener('message', async ({ data: eventData }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isValid && isDifficultyOdd) {
|
if (isValid && isDifficultyOdd) {
|
||||||
if ((hashArray[requiredZeroBytes] >> 4) !== 0) {
|
if (hashArray[requiredZeroBytes] >> 4 !== 0) {
|
||||||
isValid = false;
|
isValid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,10 @@ const calculateSHA256 = async (input: string) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const toHexString = (byteArray: Uint8Array) => {
|
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 }) => {
|
addEventListener("message", async ({ data: eventData }) => {
|
||||||
@@ -31,7 +34,7 @@ addEventListener("message", async ({ data: eventData }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isValid && isDifficultyOdd) {
|
if (isValid && isDifficultyOdd) {
|
||||||
if ((hashArray[requiredZeroBytes] >> 4) !== 0) {
|
if (hashArray[requiredZeroBytes] >> 4 !== 0) {
|
||||||
isValid = false;
|
isValid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-11
@@ -1,14 +1,11 @@
|
|||||||
$`npm run assets`;
|
$`npm run assets`;
|
||||||
|
|
||||||
[
|
["amd64", "arm64", "ppc64le", "riscv64"].forEach((goarch) => {
|
||||||
"amd64",
|
[deb, rpm, tarball].forEach((method) =>
|
||||||
"arm64",
|
method.build({
|
||||||
"ppc64le",
|
|
||||||
"riscv64",
|
|
||||||
].forEach(goarch => {
|
|
||||||
[deb, rpm, tarball].forEach(method => method.build({
|
|
||||||
name: "anubis",
|
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.",
|
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",
|
homepage: "https://anubis.techaro.lol",
|
||||||
license: "MIT",
|
license: "MIT",
|
||||||
goarch,
|
goarch,
|
||||||
@@ -26,7 +23,7 @@ $`npm run assets`;
|
|||||||
file.install("./run/anubis@.service", `${systemd}/anubis@.service`);
|
file.install("./run/anubis@.service", `${systemd}/anubis@.service`);
|
||||||
file.install("./run/default.env", `${etc}/default.env`);
|
file.install("./run/default.env", `${etc}/default.env`);
|
||||||
|
|
||||||
$`mkdir -p ${doc}/docs`
|
$`mkdir -p ${doc}/docs`;
|
||||||
$`cp -a docs/docs ${doc}`;
|
$`cp -a docs/docs ${doc}`;
|
||||||
$`find ${doc} -name _category_.json -delete`;
|
$`find ${doc} -name _category_.json -delete`;
|
||||||
$`mkdir -p ${doc}/data`;
|
$`mkdir -p ${doc}/data`;
|
||||||
@@ -37,7 +34,8 @@ $`npm run assets`;
|
|||||||
$`cp -a data/crawlers ${doc}/data/crawlers`;
|
$`cp -a data/crawlers ${doc}/data/crawlers`;
|
||||||
$`cp -a data/meta ${doc}/data/meta`;
|
$`cp -a data/meta ${doc}/data/meta`;
|
||||||
},
|
},
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// NOTE(Xe): Fixes #217. This is a "half baked" tarball that includes the harder
|
// NOTE(Xe): Fixes #217. This is a "half baked" tarball that includes the harder
|
||||||
@@ -77,7 +75,7 @@ tarball.build({
|
|||||||
// vendor Go dependencies
|
// vendor Go dependencies
|
||||||
$`cd ${out} && go mod vendor`;
|
$`cd ${out} && go mod vendor`;
|
||||||
// build NPM-bound dependencies
|
// build NPM-bound dependencies
|
||||||
$`cd ${out} && npm ci && npm run assets && rm -rf node_modules`
|
$`cd ${out} && npm ci && npm run assets && rm -rf node_modules`;
|
||||||
// write VERSION file
|
// write VERSION file
|
||||||
$`echo ${git.tag()} > ${out}/VERSION`;
|
$`echo ${git.tag()} > ${out}/VERSION`;
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user