mirror of
https://github.com/TecharoHQ/anubis.git
synced 2026-05-09 16:42:52 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3a3e97accc | |||
| c112419c45 | |||
| 423db33e20 | |||
| 1831effb59 |
@@ -31,6 +31,3 @@ Stargate
|
|||||||
FFXIV
|
FFXIV
|
||||||
uvensys
|
uvensys
|
||||||
de
|
de
|
||||||
resourced
|
|
||||||
envoyproxy
|
|
||||||
unipromos
|
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ deps:
|
|||||||
|
|
||||||
assets: PATH:=$(PWD)/node_modules/.bin:$(PATH)
|
assets: PATH:=$(PWD)/node_modules/.bin:$(PATH)
|
||||||
assets: deps
|
assets: deps
|
||||||
$(NPM) run assets
|
$(GO) generate ./...
|
||||||
|
./web/build.sh
|
||||||
|
./xess/build.sh
|
||||||
|
|
||||||
build: assets
|
build: assets
|
||||||
$(GO) build -o ./var/anubis ./cmd/anubis
|
$(GO) build -o ./var/anubis ./cmd/anubis
|
||||||
|
|||||||
@@ -8,5 +8,4 @@
|
|||||||
- import: (data)/crawlers/marginalia.yaml
|
- import: (data)/crawlers/marginalia.yaml
|
||||||
- import: (data)/crawlers/mojeekbot.yaml
|
- import: (data)/crawlers/mojeekbot.yaml
|
||||||
- import: (data)/crawlers/commoncrawl.yaml
|
- import: (data)/crawlers/commoncrawl.yaml
|
||||||
- import: (data)/crawlers/wikimedia-citoid.yaml
|
|
||||||
- import: (data)/crawlers/yandexbot.yaml
|
- import: (data)/crawlers/yandexbot.yaml
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
# Wikimedia Foundation citation services
|
|
||||||
# https://www.mediawiki.org/wiki/Citoid
|
|
||||||
|
|
||||||
- name: wikimedia-citoid
|
|
||||||
user_agent_regex: "Citoid/WMF"
|
|
||||||
action: ALLOW
|
|
||||||
remote_addresses: [
|
|
||||||
"208.80.152.0/22",
|
|
||||||
"2620:0:860::/46",
|
|
||||||
]
|
|
||||||
|
|
||||||
- name: wikimedia-zotero-translation-server
|
|
||||||
user_agent_regex: "ZoteroTranslationServer/WMF"
|
|
||||||
action: ALLOW
|
|
||||||
remote_addresses: [
|
|
||||||
"208.80.152.0/22",
|
|
||||||
"2620:0:860::/46",
|
|
||||||
]
|
|
||||||
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- fix: prevent nil pointer panic in challenge validation when threshold rules match during PassChallenge (#1463)
|
- fix: prevent nil pointer panic in challenge validation when threshold rules match during PassChallenge (#1463)
|
||||||
- Instruct reverse proxies to not cache error pages.
|
- Instruct reverse proxies to not cache error pages.
|
||||||
- Fixed mixed tab/space indentation in Caddy documentation code block
|
- Fixed mixed tab/space indentation in Caddy documentation code block
|
||||||
|
- Rewrite main proof of work challenge to use Preact instead of Vanilla.js ([#1149](https://github.com/TecharoHQ/anubis/issues/1149))
|
||||||
|
|
||||||
<!-- This changes the project to: -->
|
<!-- This changes the project to: -->
|
||||||
|
|
||||||
|
|||||||
@@ -22,13 +22,3 @@ If you use a browser extension such as [JShelter](https://jshelter.org/), you wi
|
|||||||
## Does Anubis mine Bitcoin?
|
## Does Anubis mine Bitcoin?
|
||||||
|
|
||||||
No. Anubis does not mine Bitcoin or any other cryptocurrency.
|
No. Anubis does not mine Bitcoin or any other cryptocurrency.
|
||||||
|
|
||||||
## I disabled Just-in-time compilation in my browser. Why is Anubis slow?
|
|
||||||
|
|
||||||
Anubis proof-of-work checks run an open source JavaScript program in your browser. These checks do a lot of complicated math and aim to be done quickly, so the execution speed depends on [Just-in-time (JIT) compilation](https://en.wikipedia.org/wiki/Just-in-time_compilation). JIT compiles JavaScript from the Internet into native machine code at runtime. The code produced by the JIT engine is almost as good as if it was written in a native programming language and compiled for your computer in particular. Without JIT, all JavaScript programs on every website you visit run through a slow interpreter.
|
|
||||||
|
|
||||||
This interpreter is much slower than native code because it has to translate each low level JavaScript operation into many dozens of calls to execute. This means that using the interpreter incurs a massive performance hit by its very nature; it takes longer to add numbers than if the CPU just added the numbers directly.
|
|
||||||
|
|
||||||
Some users choose to disable JIT as a hardening measure against theoretical browser exploits. This is a reasonable choice if you face targeted attacks from well-resourced adversaries (such as nation-state actors), but it comes with real performance costs.
|
|
||||||
|
|
||||||
If you've disabled JIT and find Anubis checks slow, re-enabling JIT is the fix. There is no way for Anubis to work around this on our end.
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
module github.com/TecharoHQ/anubis
|
module github.com/TecharoHQ/anubis
|
||||||
|
|
||||||
go 1.25.0
|
go 1.24.2
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/TecharoHQ/thoth-proto v0.5.0
|
github.com/TecharoHQ/thoth-proto v0.5.0
|
||||||
@@ -50,7 +50,7 @@ require (
|
|||||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||||
github.com/ProtonMail/go-crypto v1.3.0 // indirect
|
github.com/ProtonMail/go-crypto v1.3.0 // indirect
|
||||||
github.com/Songmu/gitconfig v0.2.1 // indirect
|
github.com/Songmu/gitconfig v0.2.1 // indirect
|
||||||
github.com/TecharoHQ/yeet v0.5.0 // indirect
|
github.com/TecharoHQ/yeet v0.6.3 // indirect
|
||||||
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e // indirect
|
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e // indirect
|
||||||
github.com/andybalholm/brotli v1.2.0 // indirect
|
github.com/andybalholm/brotli v1.2.0 // indirect
|
||||||
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
|
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
|
||||||
@@ -188,9 +188,9 @@ require (
|
|||||||
golang.org/x/mod v0.31.0 // indirect
|
golang.org/x/mod v0.31.0 // indirect
|
||||||
golang.org/x/oauth2 v0.32.0 // indirect
|
golang.org/x/oauth2 v0.32.0 // indirect
|
||||||
golang.org/x/sync v0.19.0 // indirect
|
golang.org/x/sync v0.19.0 // indirect
|
||||||
golang.org/x/sys v0.42.0 // indirect
|
golang.org/x/sys v0.39.0 // indirect
|
||||||
golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc // indirect
|
golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc // indirect
|
||||||
golang.org/x/term v0.40.0 // indirect
|
golang.org/x/term v0.38.0 // indirect
|
||||||
golang.org/x/tools v0.40.0 // indirect
|
golang.org/x/tools v0.40.0 // indirect
|
||||||
golang.org/x/vuln v1.1.4 // indirect
|
golang.org/x/vuln v1.1.4 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect
|
||||||
@@ -198,7 +198,7 @@ require (
|
|||||||
google.golang.org/protobuf v1.36.11 // indirect
|
google.golang.org/protobuf v1.36.11 // indirect
|
||||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||||
honnef.co/go/tools v0.6.1 // indirect
|
honnef.co/go/tools v0.6.1 // indirect
|
||||||
mvdan.cc/sh/v3 v3.13.0 // indirect
|
mvdan.cc/sh/v3 v3.12.0 // indirect
|
||||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
|
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -212,5 +212,4 @@ tool (
|
|||||||
golang.org/x/tools/cmd/stringer
|
golang.org/x/tools/cmd/stringer
|
||||||
golang.org/x/vuln/cmd/govulncheck
|
golang.org/x/vuln/cmd/govulncheck
|
||||||
honnef.co/go/tools/cmd/staticcheck
|
honnef.co/go/tools/cmd/staticcheck
|
||||||
mvdan.cc/sh/v3/cmd/gosh
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -31,12 +31,14 @@ github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f h1:tCbYj7/299ek
|
|||||||
github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f/go.mod h1:gcr0kNtGBqin9zDW9GOHcVntrwnjrK+qdJ06mWYBybw=
|
github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f/go.mod h1:gcr0kNtGBqin9zDW9GOHcVntrwnjrK+qdJ06mWYBybw=
|
||||||
github.com/ProtonMail/gopenpgp/v2 v2.7.1 h1:Awsg7MPc2gD3I7IFac2qE3Gdls0lZW8SzrFZ3k1oz0s=
|
github.com/ProtonMail/gopenpgp/v2 v2.7.1 h1:Awsg7MPc2gD3I7IFac2qE3Gdls0lZW8SzrFZ3k1oz0s=
|
||||||
github.com/ProtonMail/gopenpgp/v2 v2.7.1/go.mod h1:/BU5gfAVwqyd8EfC3Eu7zmuhwYQpKs+cGD8M//iiaxs=
|
github.com/ProtonMail/gopenpgp/v2 v2.7.1/go.mod h1:/BU5gfAVwqyd8EfC3Eu7zmuhwYQpKs+cGD8M//iiaxs=
|
||||||
|
github.com/ProtonMail/gopenpgp/v3 v3.3.0 h1:N6rHCH5PWwB6zSRMgRj1EbAMQHUAAHxH3Oo4KibsPwY=
|
||||||
|
github.com/ProtonMail/gopenpgp/v3 v3.3.0/go.mod h1:J+iNPt0/5EO9wRt7Eit9dRUlzyu3hiGX3zId6iuaKOk=
|
||||||
github.com/Songmu/gitconfig v0.2.1 h1:cZsqELfMtxWVI8ovq17gbvsR4qLfoYLAiXy5GwtJWbk=
|
github.com/Songmu/gitconfig v0.2.1 h1:cZsqELfMtxWVI8ovq17gbvsR4qLfoYLAiXy5GwtJWbk=
|
||||||
github.com/Songmu/gitconfig v0.2.1/go.mod h1:XM4O3SoXFnli9Ql2G7qXK2Fg7LJwf7Hs8GLFEOJlzmM=
|
github.com/Songmu/gitconfig v0.2.1/go.mod h1:XM4O3SoXFnli9Ql2G7qXK2Fg7LJwf7Hs8GLFEOJlzmM=
|
||||||
github.com/TecharoHQ/thoth-proto v0.5.0 h1:Fa663s4soYiURSU8MfW9tZ2wF+LsCRSaYmjUSyagfBM=
|
github.com/TecharoHQ/thoth-proto v0.5.0 h1:Fa663s4soYiURSU8MfW9tZ2wF+LsCRSaYmjUSyagfBM=
|
||||||
github.com/TecharoHQ/thoth-proto v0.5.0/go.mod h1:C/U7FqTxpVn4V/qebC/GcW32I0h9xzsmWehF27KFOJs=
|
github.com/TecharoHQ/thoth-proto v0.5.0/go.mod h1:C/U7FqTxpVn4V/qebC/GcW32I0h9xzsmWehF27KFOJs=
|
||||||
github.com/TecharoHQ/yeet v0.5.0 h1:6zL/9q0cnAI/79VA7fggcxDowzPA6D76I7+rvDLHNlM=
|
github.com/TecharoHQ/yeet v0.6.3 h1:Iev6TYt/tpFYU73kbkNIYjCObYTvlihtby+htGF4Us8=
|
||||||
github.com/TecharoHQ/yeet v0.5.0/go.mod h1:qjWkZGADLgzB+bdm8W1GhdSBbwxVskdrvXssKraTSwQ=
|
github.com/TecharoHQ/yeet v0.6.3/go.mod h1:ltt+PWPjnvmQJxEHsdJ5K9u3GoWK83vSLWCCp8XbxqI=
|
||||||
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e h1:HjVbSQHy+dnlS6C3XajZ69NYAb5jbGNfHanvm1+iYlo=
|
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e h1:HjVbSQHy+dnlS6C3XajZ69NYAb5jbGNfHanvm1+iYlo=
|
||||||
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e/go.mod h1:3mnrkvGpurZ4ZrTDbYU84xhwXW2TjTKShSwjRi2ihfQ=
|
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e/go.mod h1:3mnrkvGpurZ4ZrTDbYU84xhwXW2TjTKShSwjRi2ihfQ=
|
||||||
github.com/a-h/templ v0.3.960 h1:trshEpGa8clF5cdI39iY4ZrZG8Z/QixyzEyUnA7feTM=
|
github.com/a-h/templ v0.3.960 h1:trshEpGa8clF5cdI39iY4ZrZG8Z/QixyzEyUnA7feTM=
|
||||||
@@ -493,8 +495,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
|
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||||
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc h1:bH6xUXay0AIFMElXG2rQ4uiE+7ncwtiOdPfYK1NK2XA=
|
golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc h1:bH6xUXay0AIFMElXG2rQ4uiE+7ncwtiOdPfYK1NK2XA=
|
||||||
golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ=
|
golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
@@ -502,8 +504,8 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX
|
|||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||||
golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg=
|
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
|
||||||
golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM=
|
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
@@ -557,8 +559,8 @@ honnef.co/go/tools v0.6.1 h1:R094WgE8K4JirYjBaOpz/AvTyUu/3wbmAoskKN/pxTI=
|
|||||||
honnef.co/go/tools v0.6.1/go.mod h1:3puzxxljPCe8RGJX7BIy1plGbxEOZni5mR2aXe3/uk4=
|
honnef.co/go/tools v0.6.1/go.mod h1:3puzxxljPCe8RGJX7BIy1plGbxEOZni5mR2aXe3/uk4=
|
||||||
k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE=
|
k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE=
|
||||||
k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
|
k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
|
||||||
mvdan.cc/sh/v3 v3.13.0 h1:dSfq/MVsY4w0Vsi6Lbs0IcQquMVqLdKLESAOZjuHdLg=
|
mvdan.cc/sh/v3 v3.12.0 h1:ejKUR7ONP5bb+UGHGEG/k9V5+pRVIyD+LsZz7o8KHrI=
|
||||||
mvdan.cc/sh/v3 v3.13.0/go.mod h1:KV1GByGPc/Ho0X1E6Uz9euhsIQEj4hwyKnodLlFLoDM=
|
mvdan.cc/sh/v3 v3.12.0/go.mod h1:Se6Cj17eYSn+sNooLZiEUnNNmNxg0imoYlTu4CyaGyg=
|
||||||
pault.ag/go/debian v0.18.0 h1:nr0iiyOU5QlG1VPnhZLNhnCcHx58kukvBJp+dvaM6CQ=
|
pault.ag/go/debian v0.18.0 h1:nr0iiyOU5QlG1VPnhZLNhnCcHx58kukvBJp+dvaM6CQ=
|
||||||
pault.ag/go/debian v0.18.0/go.mod h1:JFl0XWRCv9hWBrB5MDDZjA5GSEs1X3zcFK/9kCNIUmE=
|
pault.ag/go/debian v0.18.0/go.mod h1:JFl0XWRCv9hWBrB5MDDZjA5GSEs1X3zcFK/9kCNIUmE=
|
||||||
pault.ag/go/topsort v0.1.1 h1:L0QnhUly6LmTv0e3DEzbN2q6/FGgAcQvaEw65S53Bg4=
|
pault.ag/go/topsort v0.1.1 h1:L0QnhUly6LmTv0e3DEzbN2q6/FGgAcQvaEw65S53Bg4=
|
||||||
|
|||||||
+1
-1
@@ -141,7 +141,7 @@ func (s *Server) issueChallenge(ctx context.Context, r *http.Request, lg *slog.L
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
lg.Info("new challenge issued", "challenge", id.String())
|
lg.Info("new challenge issued", "challenge", id.String(), "method", chall.Method)
|
||||||
|
|
||||||
return &chall, err
|
return &chall, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ LICENSE='/*
|
|||||||
@licstart The following is the entire license notice for the
|
@licstart The following is the entire license notice for the
|
||||||
JavaScript code in this page.
|
JavaScript code in this page.
|
||||||
|
|
||||||
Copyright (c) 2026 Xe Iaso <xe.iaso@techaro.lol>
|
Copyright (c) 2025 Xe Iaso <xe.iaso@techaro.lol>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import (
|
|||||||
"github.com/a-h/templ"
|
"github.com/a-h/templ"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate go tool gosh ./build.sh
|
//go:generate ./build.sh
|
||||||
//go:generate go tool github.com/a-h/templ/cmd/templ generate
|
//go:generate go tool github.com/a-h/templ/cmd/templ generate
|
||||||
|
|
||||||
//go:embed static/app.js
|
//go:embed static/app.js
|
||||||
|
|||||||
@@ -7,13 +7,12 @@ import (
|
|||||||
|
|
||||||
templ page(localizer *localization.SimpleLocalizer) {
|
templ page(localizer *localization.SimpleLocalizer) {
|
||||||
<div class="centered-div">
|
<div class="centered-div">
|
||||||
<img id="image" style="width:100%;max-width:256px;" src={ anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/img/pensive.webp?cacheBuster=" + anubis.Version }/>
|
<img style="display:none;" src={ anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/img/happy.webp?cacheBuster=" + anubis.Version }/>
|
||||||
<img style="display:none;" style="width:100%;max-width:256px;" src={ anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/img/happy.webp?cacheBuster=" + anubis.Version }/>
|
<div id="app">
|
||||||
|
<img style="width:100%;max-width:256px;" src={ anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/img/pensive.webp?cacheBuster=" + anubis.Version }/>
|
||||||
<p id="status">{ localizer.T("loading") }</p>
|
<p id="status">{ localizer.T("loading") }</p>
|
||||||
<script async type="module" src={ anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/js/main.mjs?cacheBuster=" + anubis.Version }></script>
|
|
||||||
<div id="progress" role="progressbar" aria-labelledby="status">
|
|
||||||
<div class="bar-inner"></div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<script async type="module" src={ anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/js/main.mjs?cacheBuster=" + anubis.Version }></script>
|
||||||
<details>
|
<details>
|
||||||
if anubis.UseSimplifiedExplanation {
|
if anubis.UseSimplifiedExplanation {
|
||||||
<p>
|
<p>
|
||||||
|
|||||||
+16
-16
@@ -34,27 +34,27 @@ func page(localizer *localization.SimpleLocalizer) templ.Component {
|
|||||||
templ_7745c5c3_Var1 = templ.NopComponent
|
templ_7745c5c3_Var1 = templ.NopComponent
|
||||||
}
|
}
|
||||||
ctx = templ.ClearChildren(ctx)
|
ctx = templ.ClearChildren(ctx)
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"centered-div\"><img id=\"image\" style=\"width:100%;max-width:256px;\" src=\"")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"centered-div\"><img style=\"display:none;\" src=\"")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
var templ_7745c5c3_Var2 string
|
var templ_7745c5c3_Var2 string
|
||||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/img/pensive.webp?cacheBuster=" + anubis.Version)
|
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/img/happy.webp?cacheBuster=" + anubis.Version)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `proofofwork.templ`, Line: 10, Col: 165}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `proofofwork.templ`, Line: 10, Col: 138}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\"> <img style=\"display:none;\" style=\"width:100%;max-width:256px;\" src=\"")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\"><div id=\"app\"><img style=\"width:100%;max-width:256px;\" src=\"")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
var templ_7745c5c3_Var3 string
|
var templ_7745c5c3_Var3 string
|
||||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/img/happy.webp?cacheBuster=" + anubis.Version)
|
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/img/pensive.webp?cacheBuster=" + anubis.Version)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `proofofwork.templ`, Line: 11, Col: 174}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `proofofwork.templ`, Line: 12, Col: 155}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -67,26 +67,26 @@ func page(localizer *localization.SimpleLocalizer) templ.Component {
|
|||||||
var templ_7745c5c3_Var4 string
|
var templ_7745c5c3_Var4 string
|
||||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("loading"))
|
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("loading"))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `proofofwork.templ`, Line: 12, Col: 41}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `proofofwork.templ`, Line: 13, Col: 42}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "</p><script async type=\"module\" src=\"")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "</p></div><script async type=\"module\" src=\"")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
var templ_7745c5c3_Var5 string
|
var templ_7745c5c3_Var5 string
|
||||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/js/main.mjs?cacheBuster=" + anubis.Version)
|
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/js/main.mjs?cacheBuster=" + anubis.Version)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `proofofwork.templ`, Line: 13, Col: 136}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `proofofwork.templ`, Line: 15, Col: 136}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\"></script><div id=\"progress\" role=\"progressbar\" aria-labelledby=\"status\"><div class=\"bar-inner\"></div></div><details>")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\"></script><details>")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
@@ -98,7 +98,7 @@ func page(localizer *localization.SimpleLocalizer) templ.Component {
|
|||||||
var templ_7745c5c3_Var6 string
|
var templ_7745c5c3_Var6 string
|
||||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("simplified_explanation"))
|
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("simplified_explanation"))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `proofofwork.templ`, Line: 20, Col: 44}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `proofofwork.templ`, Line: 19, Col: 44}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -116,7 +116,7 @@ func page(localizer *localization.SimpleLocalizer) templ.Component {
|
|||||||
var templ_7745c5c3_Var7 string
|
var templ_7745c5c3_Var7 string
|
||||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("ai_companies_explanation"))
|
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("ai_companies_explanation"))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `proofofwork.templ`, Line: 24, Col: 46}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `proofofwork.templ`, Line: 23, Col: 46}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -129,7 +129,7 @@ func page(localizer *localization.SimpleLocalizer) templ.Component {
|
|||||||
var templ_7745c5c3_Var8 string
|
var templ_7745c5c3_Var8 string
|
||||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("anubis_compromise"))
|
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("anubis_compromise"))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `proofofwork.templ`, Line: 27, Col: 39}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `proofofwork.templ`, Line: 26, Col: 39}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -142,7 +142,7 @@ func page(localizer *localization.SimpleLocalizer) templ.Component {
|
|||||||
var templ_7745c5c3_Var9 string
|
var templ_7745c5c3_Var9 string
|
||||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("hack_purpose"))
|
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("hack_purpose"))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `proofofwork.templ`, Line: 30, Col: 34}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `proofofwork.templ`, Line: 29, Col: 34}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -155,7 +155,7 @@ func page(localizer *localization.SimpleLocalizer) templ.Component {
|
|||||||
var templ_7745c5c3_Var10 string
|
var templ_7745c5c3_Var10 string
|
||||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("jshelter_note"))
|
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("jshelter_note"))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `proofofwork.templ`, Line: 33, Col: 35}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `proofofwork.templ`, Line: 32, Col: 35}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -173,7 +173,7 @@ func page(localizer *localization.SimpleLocalizer) templ.Component {
|
|||||||
var templ_7745c5c3_Var11 string
|
var templ_7745c5c3_Var11 string
|
||||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("javascript_required"))
|
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("javascript_required"))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `proofofwork.templ`, Line: 39, Col: 40}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `proofofwork.templ`, Line: 38, Col: 40}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_finished_reading": "Čtení dokončeno, pokračovat →",
|
"js_finished_reading": "Čtení dokončeno, pokračovat →",
|
||||||
"js_calculation_error": "Chyba výpočtu!",
|
"js_calculation_error": "Chyba výpočtu!",
|
||||||
"js_calculation_error_msg": "Nepodařilo se vypočítat výzvu:",
|
"js_calculation_error_msg": "Nepodařilo se vypočítat výzvu:",
|
||||||
"missing_required_forwarded_headers": "Chybějící požadované hlavičky X-Forwarded-*"
|
"missing_required_forwarded_headers": "Chybějící požadované hlavičky X-Forwarded-*",
|
||||||
|
"js_challenge_data_missing": "Data pro ověření chybí. Načtěte prosím stránku znovu."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_iterations": "Iterationen",
|
"js_iterations": "Iterationen",
|
||||||
"js_finished_reading": "Fertig gelesen – weiter zur Seite →",
|
"js_finished_reading": "Fertig gelesen – weiter zur Seite →",
|
||||||
"js_calculation_error": "Berechnungsfehler!",
|
"js_calculation_error": "Berechnungsfehler!",
|
||||||
"js_calculation_error_msg": "Fehler bei der Berechnung der Prüfung:"
|
"js_calculation_error_msg": "Fehler bei der Berechnung der Prüfung:",
|
||||||
|
"js_challenge_data_missing": "Die Prüfungsdaten fehlen. Bitte laden Sie die Seite neu."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_iterations": "iterations",
|
"js_iterations": "iterations",
|
||||||
"js_finished_reading": "I've finished reading, continue →",
|
"js_finished_reading": "I've finished reading, continue →",
|
||||||
"js_calculation_error": "Calculation error!",
|
"js_calculation_error": "Calculation error!",
|
||||||
"js_calculation_error_msg": "Failed to calculate challenge:"
|
"js_calculation_error_msg": "Failed to calculate challenge:",
|
||||||
|
"js_challenge_data_missing": "Challenge data is missing. Please reload the page."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_calculation_error": "¡Error de cálculo!",
|
"js_calculation_error": "¡Error de cálculo!",
|
||||||
"js_calculation_error_msg": "Falló al calcular el desafío:",
|
"js_calculation_error_msg": "Falló al calcular el desafío:",
|
||||||
"missing_required_forwarded_headers": "Faltan los encabezados X-Forwarded-* requeridos",
|
"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 <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Prueba de trabajo</a>. La tarea se calcula en unos segundos y se le concede acceso al sitio web. Gracias por su comprensión y paciencia."
|
"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 <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Prueba de trabajo</a>. La tarea se calcula en unos segundos y se le concede acceso al sitio web. Gracias por su comprensión y paciencia.",
|
||||||
|
"js_challenge_data_missing": "Faltan los datos del desafío. Por favor, recargue la página."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_calculation_error": "Arvutamise viga!",
|
"js_calculation_error": "Arvutamise viga!",
|
||||||
"js_calculation_error_msg": "Ei suutnud kontrolli arvutada:",
|
"js_calculation_error_msg": "Ei suutnud kontrolli arvutada:",
|
||||||
"missing_required_forwarded_headers": "Puuduvad nõutud X-Forwarded-* päised",
|
"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 <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Töötõendiks</a>. Ülesanne arvutatakse mõne sekundiga ja teile antakse juurdepääs veebisaidile. Täname teid mõistva suhtumise ja kannatlikkuse eest."
|
"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 <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Töötõendiks</a>. Ülesanne arvutatakse mõne sekundiga ja teile antakse juurdepääs veebisaidile. Täname teid mõistva suhtumise ja kannatlikkuse eest.",
|
||||||
|
"js_challenge_data_missing": "Kontrollülesande andmed puuduvad. Palun laadige leht uuesti."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_calculation_error": "Laskentavirhe!",
|
"js_calculation_error": "Laskentavirhe!",
|
||||||
"js_calculation_error_msg": "Haasteen laskenta ei onnistunut:",
|
"js_calculation_error_msg": "Haasteen laskenta ei onnistunut:",
|
||||||
"missing_required_forwarded_headers": "Puuttuvat vaaditut X-Forwarded-* otsikot",
|
"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ä <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Työtodistus</a>. Tehtävä lasketaan muutamassa sekunnissa ja saat pääsyn verkkosivustolle. Kiitos ymmärryksestäsi ja kärsivällisyydestäsi."
|
"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ä <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Työtodistus</a>. Tehtävä lasketaan muutamassa sekunnissa ja saat pääsyn verkkosivustolle. Kiitos ymmärryksestäsi ja kärsivällisyydestäsi.",
|
||||||
|
"js_challenge_data_missing": "Haastetiedot puuttuvat. Lataa sivu uudelleen."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_calculation_error": "Error sa pagkalkula!",
|
"js_calculation_error": "Error sa pagkalkula!",
|
||||||
"js_calculation_error_msg": "Nabigong ikalkula ang hamon:",
|
"js_calculation_error_msg": "Nabigong ikalkula ang hamon:",
|
||||||
"missing_required_forwarded_headers": "Nawawala ang kinakailangang X-Forwarded-* na mga header",
|
"missing_required_forwarded_headers": "Nawawala ang kinakailangang X-Forwarded-* na mga header",
|
||||||
"simplified_explanation": "Ito ay isang panukala laban sa mga bot at malisyosong mga kahilingan na katulad ng isang CAPTCHA. Gayunpaman, sa halip na ikaw mismo ang gumawa ng trabaho, binibigyan ang iyong browser ng isang gawain sa pagkalkula na kailangan nitong lutasin upang matiyak na ito ay isang wastong kliyente. Ang konseptong ito ay tinatawag na <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Proof of Work</a>. Ang gawain ay kinakalkula sa loob ng ilang segundo at binibigyan ka ng access sa website. Salamat sa iyong pag-unawa at pasensya."
|
"simplified_explanation": "Ito ay isang panukala laban sa mga bot at malisyosong mga kahilingan na katulad ng isang CAPTCHA. Gayunpaman, sa halip na ikaw mismo ang gumawa ng trabaho, binibigyan ang iyong browser ng isang gawain sa pagkalkula na kailangan nitong lutasin upang matiyak na ito ay isang wastong kliyente. Ang konseptong ito ay tinatawag na <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Proof of Work</a>. Ang gawain ay kinakalkula sa loob ng ilang segundo at binibigyan ka ng access sa website. Salamat sa iyong pag-unawa at pasensya.",
|
||||||
|
"js_challenge_data_missing": "Nawawala ang data ng hamon. Mangyaring i-reload ang pahina."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_calculation_error": "Erreur de calcul !",
|
"js_calculation_error": "Erreur de calcul !",
|
||||||
"js_calculation_error_msg": "Échec du calcul du défi :",
|
"js_calculation_error_msg": "Échec du calcul du défi :",
|
||||||
"missing_required_forwarded_headers": "En-têtes X-Forwarded-* manquants",
|
"missing_required_forwarded_headers": "En-têtes X-Forwarded-* manquants",
|
||||||
"simplified_explanation": "Ceci est 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 confirmer qu'il est un client valide. Ce concept est nommé <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Preuve de travail</a>. La tâche s'effectue en quelques secondes, puis vous avez accès au site Web. Merci pour votre compréhension et votre patience."
|
"simplified_explanation": "Ceci est 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 confirmer qu'il est un client valide. Ce concept est nommé <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Preuve de travail</a>. La tâche s'effectue en quelques secondes, puis vous avez accès au site Web. Merci pour votre compréhension et votre patience.",
|
||||||
|
"js_challenge_data_missing": "Les données du défi sont manquantes. Veuillez recharger la page."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_calculation_error": "Reiknivilla!",
|
"js_calculation_error": "Reiknivilla!",
|
||||||
"js_calculation_error_msg": "Mistókst að reikna áskorun:",
|
"js_calculation_error_msg": "Mistókst að reikna áskorun:",
|
||||||
"missing_required_forwarded_headers": "Vantar nauðsynleg X-Forwarded-* hausar",
|
"missing_required_forwarded_headers": "Vantar nauðsynleg X-Forwarded-* hausar",
|
||||||
"simplified_explanation": "Þetta er ráðstöfun gegn vélmennum og illa meinandi beiðnum, sem virkar svipað og CAPTCHA-mennskupróf. Hins vegar; í stað þess að þurfa að vinna sjálfur, fær vafrinn þinn útreikningsverkefni sem hann þarf að leysa til að tryggja að hann sé gildur biðlari. Þetta hugtak er kallað <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Sönnun-á-vinnu</a>. Verkefnið er reiknað á nokkrum sekúndum og þú færð aðgang að vefsíðunni. Takk fyrir skilninginn og þolinmæðina."
|
"simplified_explanation": "Þetta er ráðstöfun gegn vélmennum og illa meinandi beiðnum, sem virkar svipað og CAPTCHA-mennskupróf. Hins vegar; í stað þess að þurfa að vinna sjálfur, fær vafrinn þinn útreikningsverkefni sem hann þarf að leysa til að tryggja að hann sé gildur biðlari. Þetta hugtak er kallað <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Sönnun-á-vinnu</a>. Verkefnið er reiknað á nokkrum sekúndum og þú færð aðgang að vefsíðunni. Takk fyrir skilninginn og þolinmæðina.",
|
||||||
|
"js_challenge_data_missing": "Áskorunargögn vantar. Vinsamlegast endurhlaðið síðuna."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_calculation_error": "Errore nel calcolo!",
|
"js_calculation_error": "Errore nel calcolo!",
|
||||||
"js_calculation_error_msg": "Impossibile superare il test:",
|
"js_calculation_error_msg": "Impossibile superare il test:",
|
||||||
"missing_required_forwarded_headers": "Mancano gli header X-Forwarded-* richiesti",
|
"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 <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Proof of Work</a>. Il compito viene calcolato in pochi secondi e ti viene concesso l'accesso al sito web. Grazie per la tua comprensione e pazienza."
|
"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 <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Proof of Work</a>. Il compito viene calcolato in pochi secondi e ti viene concesso l'accesso al sito web. Grazie per la tua comprensione e pazienza.",
|
||||||
|
"js_challenge_data_missing": "I dati della sfida sono mancanti. Ricarica la pagina."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
"anubis_compromise": "Anubisは妥協策です。AnubisはHashcashのようなProof-of-Work方式を採用しており、これは元々メールスパムを減らすために提案された仕組みです。個人レベルでは追加の負荷は無視できる程度ですが、大規模なスクレイピングでは負荷が積み重なり、スクレイピングのコストが大幅に増加します。",
|
"anubis_compromise": "Anubisは妥協策です。AnubisはHashcashのようなProof-of-Work方式を採用しており、これは元々メールスパムを減らすために提案された仕組みです。個人レベルでは追加の負荷は無視できる程度ですが、大規模なスクレイピングでは負荷が積み重なり、スクレイピングのコストが大幅に増加します。",
|
||||||
"hack_purpose": "最終的に、これはヘッドレスブラウザのフィンガープリントと識別に時間を費やすためのプレースホルダーソリューションです(例:フォントレンダリングの方法による)。これにより、正当なユーザーにはチャレンジのプルーフオブワークページを提示する必要がなくなります。",
|
"hack_purpose": "最終的に、これはヘッドレスブラウザのフィンガープリントと識別に時間を費やすためのプレースホルダーソリューションです(例:フォントレンダリングの方法による)。これにより、正当なユーザーにはチャレンジのプルーフオブワークページを提示する必要がなくなります。",
|
||||||
"jshelter_note": "Anubisは、JShelterのようなプラグインが無効化する最新のJavaScript機能を必要とします。このドメインではJShelterや同様のプラグインを無効にしてください。",
|
"jshelter_note": "Anubisは、JShelterのようなプラグインが無効化する最新のJavaScript機能を必要とします。このドメインではJShelterや同様のプラグインを無効にしてください。",
|
||||||
"version_info": "このウェブサイトはAnubisで動作しています バージョン",
|
"version_info": "このウェブサイトはAnubisバージョンで動作しています",
|
||||||
"try_again": "再試行",
|
"try_again": "再試行",
|
||||||
"go_home": "ホームに戻る",
|
"go_home": "ホームに戻る",
|
||||||
"contact_webmaster": "もしブロックされるべきでないと思われる場合は、ウェブマスターにご連絡ください:",
|
"contact_webmaster": "もしブロックされるべきでないと思われる場合は、ウェブマスターにご連絡ください:",
|
||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_calculation_error": "計算エラー!",
|
"js_calculation_error": "計算エラー!",
|
||||||
"js_calculation_error_msg": "チャレンジの計算に失敗しました:",
|
"js_calculation_error_msg": "チャレンジの計算に失敗しました:",
|
||||||
"missing_required_forwarded_headers": "必要な X-Forwarded-* ヘッダーがありません",
|
"missing_required_forwarded_headers": "必要な X-Forwarded-* ヘッダーがありません",
|
||||||
"simplified_explanation": "これは、CAPTCHAと同様の、ボットや悪意のあるリクエストに対する対策です。ただし、自分で作業する代わりに、ブラウザに計算タスクが与えられ、それを解決して有効なクライアントであることを確認する必要があります。この概念は<a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Proof of Work</a>と呼ばれます。タスクは数秒で計算され、ウェブサイトへのアクセスが許可されます。ご理解とご協力をお願いいたします。"
|
"simplified_explanation": "これは、CAPTCHAと同様の、ボットや悪意のあるリクエストに対する対策です。ただし、自分で作業する代わりに、ブラウザに計算タスクが与えられ、それを解決して有効なクライアントであることを確認する必要があります。この概念は<a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Proof of Work</a>と呼ばれます。タスクは数秒で計算され、ウェブサイトへのアクセスが許可されます。ご理解とご協力をお願いいたします。",
|
||||||
|
"js_challenge_data_missing": "チャレンジデータがありません。ページを再読み込みしてください。"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
"invalid_redirect": "Netinkamas nukreipimas",
|
"invalid_redirect": "Netinkamas nukreipimas",
|
||||||
"redirect_not_parseable": "Nukreipimo adreso nepavyko išanalizuoti",
|
"redirect_not_parseable": "Nukreipimo adreso nepavyko išanalizuoti",
|
||||||
"redirect_domain_not_allowed": "Nukreipimo domenas neleistinas",
|
"redirect_domain_not_allowed": "Nukreipimo domenas neleistinas",
|
||||||
"missing_required_forwarded_headers": "Trūksta būtinų „X-Forwarded-*“ antraščių",
|
"missing_required_forwarded_headers": "Trūksta privalomų X-Forwarded-* antraščių",
|
||||||
"failed_to_sign_jwt": "nepavyko pasirašyti JWT",
|
"failed_to_sign_jwt": "nepavyko pasirašyti JWT",
|
||||||
"invalid_invocation": "Netinkamas kreipinys į „MakeChallenge“",
|
"invalid_invocation": "Netinkamas kreipinys į „MakeChallenge“",
|
||||||
"client_error_browser": "Problema klientinėje dalyje: įsitikinkite, jog jūsų naršyklė nepasenusi ir bandykite dar kartą.",
|
"client_error_browser": "Problema klientinėje dalyje: įsitikinkite, jog jūsų naršyklė nepasenusi ir bandykite dar kartą.",
|
||||||
@@ -63,5 +63,5 @@
|
|||||||
"js_finished_reading": "Viską perskaičiau, tęskime →",
|
"js_finished_reading": "Viską perskaičiau, tęskime →",
|
||||||
"js_calculation_error": "Skaičiavimo klaida!",
|
"js_calculation_error": "Skaičiavimo klaida!",
|
||||||
"js_calculation_error_msg": "Nepavyko įveikti iššūkio:",
|
"js_calculation_error_msg": "Nepavyko įveikti iššūkio:",
|
||||||
"missing_required_forwarded_headers": "Trūksta privalomų X-Forwarded-* antraščių"
|
"js_challenge_data_missing": "Trūksta iššūkio duomenų. Prašome perkrauti puslapį."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_calculation_error": "Beregningsfeil!",
|
"js_calculation_error": "Beregningsfeil!",
|
||||||
"js_calculation_error_msg": "Mislyktes i å beregne utfordring:",
|
"js_calculation_error_msg": "Mislyktes i å beregne utfordring:",
|
||||||
"missing_required_forwarded_headers": "Mangler nødvendige X-Forwarded-* header",
|
"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 <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Proof of Work</a>. Oppgaven beregnes på noen få sekunder, og du får tilgang til nettstedet. Takk for din forståelse og tålmodighet."
|
"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 <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Proof of Work</a>. Oppgaven beregnes på noen få sekunder, og du får tilgang til nettstedet. Takk for din forståelse og tålmodighet.",
|
||||||
|
"js_challenge_data_missing": "Utfordringsdata mangler. Vennligst last inn siden på nytt."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_calculation_error": "Rekenfout!",
|
"js_calculation_error": "Rekenfout!",
|
||||||
"js_calculation_error_msg": "Uitdaging niet berekend:",
|
"js_calculation_error_msg": "Uitdaging niet berekend:",
|
||||||
"missing_required_forwarded_headers": "Ontbrekende vereiste X-Forwarded-* headers",
|
"missing_required_forwarded_headers": "Ontbrekende vereiste X-Forwarded-* headers",
|
||||||
"simplified_explanation": "Dit is een maatregel tegen bots en kwaadwillende verzoeken, vergelijkbaar met een CAPTCHA. In plaats van dat je zelf werk moet verrichten, krijgt je browser een rekentaak die moet worden opgelost om ervoor te zorgen dat het een geldige client is. Dit concept wordt <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Proof of Work</a> genoemd. De taak wordt in een paar seconden berekend en u krijgt toegang tot de website. Bedankt voor je begrip en geduld."
|
"simplified_explanation": "Dit is een maatregel tegen bots en kwaadwillende verzoeken, vergelijkbaar met een CAPTCHA. In plaats van dat je zelf werk moet verrichten, krijgt je browser een rekentaak die moet worden opgelost om ervoor te zorgen dat het een geldige client is. Dit concept wordt <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Proof of Work</a> genoemd. De taak wordt in een paar seconden berekend en u krijgt toegang tot de website. Bedankt voor je begrip en geduld.",
|
||||||
|
"js_challenge_data_missing": "Uitdagingsgegevens ontbreken. Herlaad de pagina."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_calculation_error": "Rekningsfeil!",
|
"js_calculation_error": "Rekningsfeil!",
|
||||||
"js_calculation_error_msg": "Mislukkast i å rekna utfordring:",
|
"js_calculation_error_msg": "Mislukkast i å rekna utfordring:",
|
||||||
"missing_required_forwarded_headers": "Vantande naudsynte «X-Forwarded-*»-overskrifter",
|
"missing_required_forwarded_headers": "Vantande naudsynte «X-Forwarded-*»-overskrifter",
|
||||||
"simplified_explanation": "Dette er eit tiltak mot robotar og ondsinna førespurnader som liknar på ein CAPTCHA. Men i staden for å måtte gjera arbeidet sjølv, får netlesaren din ei utrekningsoppgåve som han må løysa for å stadfesta at han er ein gyldig klient. Dette konseptet vert kalla <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">arbeidsstadfesting</a>. Oppgåva vert rekna ut på nokre få sekund, og du får tilgang til nettstaden. Takk for forståinga di og tolmodet ditt."
|
"simplified_explanation": "Dette er eit tiltak mot robotar og ondsinna førespurnader som liknar på ein CAPTCHA. Men i staden for å måtte gjera arbeidet sjølv, får netlesaren din ei utrekningsoppgåve som han må løysa for å stadfesta at han er ein gyldig klient. Dette konseptet vert kalla <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">arbeidsstadfesting</a>. Oppgåva vert rekna ut på nokre få sekund, og du får tilgang til nettstaden. Takk for forståinga di og tolmodet ditt.",
|
||||||
|
"js_challenge_data_missing": "Utfordringsdata manglar. Last inn sida på nytt."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_iterations": "iteracji",
|
"js_iterations": "iteracji",
|
||||||
"js_finished_reading": "Skończyłem czytać, kontynuuj →",
|
"js_finished_reading": "Skończyłem czytać, kontynuuj →",
|
||||||
"js_calculation_error": "Błąd obliczeń!",
|
"js_calculation_error": "Błąd obliczeń!",
|
||||||
"js_calculation_error_msg": "Nie udało się obliczyć zadania:"
|
"js_calculation_error_msg": "Nie udało się obliczyć zadania:",
|
||||||
|
"js_challenge_data_missing": "Brak danych wyzwania. Proszę odświeżyć stronę."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_calculation_error": "Erro de cálculo!",
|
"js_calculation_error": "Erro de cálculo!",
|
||||||
"js_calculation_error_msg": "Falha ao calcular a validação:",
|
"js_calculation_error_msg": "Falha ao calcular a validação:",
|
||||||
"missing_required_forwarded_headers": "Faltam os cabeçalhos X-Forwarded-* obrigatórios",
|
"missing_required_forwarded_headers": "Faltam os cabeçalhos X-Forwarded-* obrigatórios",
|
||||||
"simplified_explanation": "Esta é uma medida contra bots e solicitações maliciosas, semelhante a um CAPTCHA. No entanto, em vez de você mesmo ter que fazer o trabalho, seu navegador recebe uma tarefa de cálculo que ele deve resolver para garantir que seja um cliente válido. Esse conceito é chamado de <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Prova de Trabalho</a>. A tarefa é calculada em poucos segundos e você tem acesso ao site. Obrigado pela sua compreensão e paciência."
|
"simplified_explanation": "Esta é uma medida contra bots e solicitações maliciosas, semelhante a um CAPTCHA. No entanto, em vez de você mesmo ter que fazer o trabalho, seu navegador recebe uma tarefa de cálculo que ele deve resolver para garantir que seja um cliente válido. Esse conceito é chamado de <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Prova de Trabalho</a>. A tarefa é calculada em poucos segundos e você tem acesso ao site. Obrigado pela sua compreensão e paciência.",
|
||||||
|
"js_challenge_data_missing": "Os dados do desafio estão ausentes. Por favor, recarregue a página."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_calculation_error": "Ошибка расчёта!",
|
"js_calculation_error": "Ошибка расчёта!",
|
||||||
"js_calculation_error_msg": "Не удалось рассчитать задачу:",
|
"js_calculation_error_msg": "Не удалось рассчитать задачу:",
|
||||||
"missing_required_forwarded_headers": "Отсутствуют требуемые заголовки X-Forwarded-*",
|
"missing_required_forwarded_headers": "Отсутствуют требуемые заголовки X-Forwarded-*",
|
||||||
"simplified_explanation": "Это мера против ботов и вредоносных запросов, аналогичная CAPTCHA. Однако вместо того, чтобы вам приходилось работать самостоятельно, вашему браузеру дается задача вычисления, которую он должен решить, чтобы убедиться, что он является действительным клиентом. Эта концепция называется <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Доказательство выполнения работы</a>. Задача рассчитывается за несколько секунд, и вам предоставляется доступ к веб-сайту. Спасибо за понимание и терпение."
|
"simplified_explanation": "Это мера против ботов и вредоносных запросов, аналогичная CAPTCHA. Однако вместо того, чтобы вам приходилось работать самостоятельно, вашему браузеру дается задача вычисления, которую он должен решить, чтобы убедиться, что он является действительным клиентом. Эта концепция называется <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Доказательство выполнения работы</a>. Задача рассчитывается за несколько секунд, и вам предоставляется доступ к веб-сайту. Спасибо за понимание и терпение.",
|
||||||
|
"js_challenge_data_missing": "Данные проверки отсутствуют. Пожалуйста, перезагрузите страницу."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_calculation_error": "Beräkningsfel!",
|
"js_calculation_error": "Beräkningsfel!",
|
||||||
"js_calculation_error_msg": "Misslyckades att kalkylera utmaning:",
|
"js_calculation_error_msg": "Misslyckades att kalkylera utmaning:",
|
||||||
"missing_required_forwarded_headers": "Saknar nödvändiga X-Forwarded-* headers",
|
"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 <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Arbetsbevis</a>. 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."
|
"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 <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">Arbetsbevis</a>. 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.",
|
||||||
|
"js_challenge_data_missing": "Utmaningsdata saknas. Vänligen ladda om sidan."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,5 +60,6 @@
|
|||||||
"js_iterations": "รอบ",
|
"js_iterations": "รอบ",
|
||||||
"js_finished_reading": "อ่านจบแล้ว ดำเนินการต่อ →",
|
"js_finished_reading": "อ่านจบแล้ว ดำเนินการต่อ →",
|
||||||
"js_calculation_error": "เกิดข้อผิดพลาดในการคำนวณ!",
|
"js_calculation_error": "เกิดข้อผิดพลาดในการคำนวณ!",
|
||||||
"js_calculation_error_msg": "ไม่สามารถคำนวณการท้าทายได้:"
|
"js_calculation_error_msg": "ไม่สามารถคำนวณการท้าทายได้:",
|
||||||
|
"js_challenge_data_missing": "ข้อมูลการท้าทายหายไป กรุณาโหลดหน้าใหม่"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_calculation_error": "Hesaplama hatası!",
|
"js_calculation_error": "Hesaplama hatası!",
|
||||||
"js_calculation_error_msg": "Zorluk hesaplaması başarısız oldu:",
|
"js_calculation_error_msg": "Zorluk hesaplaması başarısız oldu:",
|
||||||
"missing_required_forwarded_headers": "Gerekli X-Forwarded-* başlıkları eksik",
|
"missing_required_forwarded_headers": "Gerekli X-Forwarded-* başlıkları eksik",
|
||||||
"simplified_explanation": "Bu, botlara ve kötü niyetli isteklere karşı CAPTCHA'ya benzer bir önlemdir. Ancak, kendiniz çalışmak yerine, tarayıcınıza geçerli bir istemci olduğundan emin olmak için çözmesi gereken bir hesaplama görevi verilir. Bu kavrama <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">İş Kanıtı</a> denir. Görev birkaç saniye içinde hesaplanır ve web sitesine erişim hakkı kazanırsınız. Anlayışınız ve sabrınız için teşekkür ederiz."
|
"simplified_explanation": "Bu, botlara ve kötü niyetli isteklere karşı CAPTCHA'ya benzer bir önlemdir. Ancak, kendiniz çalışmak yerine, tarayıcınıza geçerli bir istemci olduğundan emin olmak için çözmesi gereken bir hesaplama görevi verilir. Bu kavrama <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">İş Kanıtı</a> denir. Görev birkaç saniye içinde hesaplanır ve web sitesine erişim hakkı kazanırsınız. Anlayışınız ve sabrınız için teşekkür ederiz.",
|
||||||
|
"js_challenge_data_missing": "Doğrulama verileri eksik. Lütfen sayfayı yeniden yükleyin."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_iterations": "ітерацій",
|
"js_iterations": "ітерацій",
|
||||||
"js_finished_reading": "Читання завершено, продовжити →",
|
"js_finished_reading": "Читання завершено, продовжити →",
|
||||||
"js_calculation_error": "Помилка обчислення!",
|
"js_calculation_error": "Помилка обчислення!",
|
||||||
"js_calculation_error_msg": "Не вдалося обчислити перевірку:"
|
"js_calculation_error_msg": "Не вдалося обчислити перевірку:",
|
||||||
|
"js_challenge_data_missing": "Дані перевірки відсутні. Будь ласка, перезавантажте сторінку."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_iterations": "lần lặp lại",
|
"js_iterations": "lần lặp lại",
|
||||||
"js_finished_reading": "Tôi đã đọc xong, tiếp tục →",
|
"js_finished_reading": "Tôi đã đọc xong, tiếp tục →",
|
||||||
"js_calculation_error": "Lỗi tính toán!",
|
"js_calculation_error": "Lỗi tính toán!",
|
||||||
"js_calculation_error_msg": "Không thể tính toán thử thách:"
|
"js_calculation_error_msg": "Không thể tính toán thử thách:",
|
||||||
|
"js_challenge_data_missing": "Thiếu dữ liệu thử thách. Vui lòng tải lại trang."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_calculation_error": "计算错误!",
|
"js_calculation_error": "计算错误!",
|
||||||
"js_calculation_error_msg": "计算挑战失败:",
|
"js_calculation_error_msg": "计算挑战失败:",
|
||||||
"missing_required_forwarded_headers": "缺少必要的 X-Forwarded-* 头",
|
"missing_required_forwarded_headers": "缺少必要的 X-Forwarded-* 头",
|
||||||
"simplified_explanation": "这是一种类似于验证码的措施,用于防止机器人和恶意请求。但是,您无需自己动手,您的浏览器会收到一个计算任务,必须解决该任务以确保它是有效的客户端。这个概念称为<a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">工作量证明</a>。该任务在几秒钟内计算完毕,您将被授予访问网站的权限。感谢您的理解和耐心。"
|
"simplified_explanation": "这是一种类似于验证码的措施,用于防止机器人和恶意请求。但是,您无需自己动手,您的浏览器会收到一个计算任务,必须解决该任务以确保它是有效的客户端。这个概念称为<a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">工作量证明</a>。该任务在几秒钟内计算完毕,您将被授予访问网站的权限。感谢您的理解和耐心。",
|
||||||
|
"js_challenge_data_missing": "验证数据缺失。请重新加载页面。"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
"js_calculation_error": "計算錯誤!",
|
"js_calculation_error": "計算錯誤!",
|
||||||
"js_calculation_error_msg": "計算挑戰失敗:",
|
"js_calculation_error_msg": "計算挑戰失敗:",
|
||||||
"missing_required_forwarded_headers": "缺少必要的 X-Forwarded-* 標頭",
|
"missing_required_forwarded_headers": "缺少必要的 X-Forwarded-* 標頭",
|
||||||
"simplified_explanation": "這是一種類似於驗證碼的措施,用於防止機器人和惡意請求。但是,您無需自己動手,您的瀏覽器會收到一個計算任務,必須解決該任務以確保它是有效的客戶端。這個概念稱為<a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">工作量證明</a>。該任務在幾秒鐘內計算完畢,您將被授予訪問網站的權限。感謝您的理解和耐心。"
|
"simplified_explanation": "這是一種類似於驗證碼的措施,用於防止機器人和惡意請求。但是,您無需自己動手,您的瀏覽器會收到一個計算任務,必須解決該任務以確保它是有效的客戶端。這個概念稱為<a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">工作量證明</a>。該任務在幾秒鐘內計算完畢,您將被授予訪問網站的權限。感謝您的理解和耐心。",
|
||||||
|
"js_challenge_data_missing": "驗證資料遺失。請重新載入頁面。"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
"test:integration": "npm run assets && go test -v ./internal/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: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",
|
"test:integration:docker": "npm run assets && go test -v ./internal/test --playwright-runner=docker",
|
||||||
"assets": "go generate ./...",
|
"assets": "go generate ./... && ./web/build.sh && ./xess/build.sh",
|
||||||
"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",
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
module github.com/TecharoHQ/anubis/test
|
module github.com/TecharoHQ/anubis/test
|
||||||
|
|
||||||
go 1.25.0
|
go 1.24.5
|
||||||
|
|
||||||
replace github.com/TecharoHQ/anubis => ..
|
replace github.com/TecharoHQ/anubis => ..
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ require (
|
|||||||
go.yaml.in/yaml/v2 v2.4.3 // indirect
|
go.yaml.in/yaml/v2 v2.4.3 // indirect
|
||||||
golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 // indirect
|
golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 // indirect
|
||||||
golang.org/x/net v0.48.0 // indirect
|
golang.org/x/net v0.48.0 // indirect
|
||||||
golang.org/x/sys v0.42.0 // indirect
|
golang.org/x/sys v0.39.0 // indirect
|
||||||
golang.org/x/text v0.32.0 // indirect
|
golang.org/x/text v0.32.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect
|
||||||
|
|||||||
+2
-2
@@ -261,8 +261,8 @@ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
|
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||||
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||||
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
|
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
|
||||||
|
|||||||
+11
-4
@@ -8,7 +8,7 @@ LICENSE='/*
|
|||||||
@licstart The following is the entire license notice for the
|
@licstart The following is the entire license notice for the
|
||||||
JavaScript code in this page.
|
JavaScript code in this page.
|
||||||
|
|
||||||
Copyright (c) 2026 Xe Iaso <xe.iaso@techaro.lol>
|
Copyright (c) 2025 Xe Iaso <xe.iaso@techaro.lol>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -41,15 +41,22 @@ cp ../lib/localization/locales/*.json static/locales/
|
|||||||
|
|
||||||
shopt -s nullglob globstar
|
shopt -s nullglob globstar
|
||||||
|
|
||||||
for file in js/**/*.ts js/**/*.mjs; do
|
for file in js/**/*.ts js/**/*.tsx js/**/*.mjs; do
|
||||||
out="static/${file}"
|
out="static/${file}"
|
||||||
if [[ "$file" == *.ts ]]; then
|
if [[ "$file" == *.tsx ]]; then
|
||||||
|
out="static/${file%.tsx}.mjs"
|
||||||
|
elif [[ "$file" == *.ts ]]; then
|
||||||
out="static/${file%.ts}.mjs"
|
out="static/${file%.ts}.mjs"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
mkdir -p "$(dirname "$out")"
|
mkdir -p "$(dirname "$out")"
|
||||||
|
|
||||||
esbuild "$file" --sourcemap --bundle --minify --outfile="$out" --banner:js="$LICENSE"
|
JSX_FLAGS=""
|
||||||
|
if [[ "$file" == *.tsx ]]; then
|
||||||
|
JSX_FLAGS="--jsx=automatic --jsx-import-source=preact"
|
||||||
|
fi
|
||||||
|
|
||||||
|
esbuild "$file" --sourcemap --bundle --minify --outfile="$out" $JSX_FLAGS --banner:js="$LICENSE"
|
||||||
gzip -f -k -n "$out"
|
gzip -f -k -n "$out"
|
||||||
zstd -f -k --ultra -22 "$out"
|
zstd -f -k --ultra -22 "$out"
|
||||||
brotli -fZk "$out"
|
brotli -fZk "$out"
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package web
|
|||||||
import "embed"
|
import "embed"
|
||||||
|
|
||||||
//go:generate go tool github.com/a-h/templ/cmd/templ generate
|
//go:generate go tool github.com/a-h/templ/cmd/templ generate
|
||||||
//go:generate go tool gosh ./build.sh
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
//go:embed static
|
//go:embed static
|
||||||
|
|||||||
-281
@@ -1,281 +0,0 @@
|
|||||||
import algorithms from "./algorithms";
|
|
||||||
|
|
||||||
// from Xeact
|
|
||||||
const u = (url: string = "", params: Record<string, any> = {}) => {
|
|
||||||
let result = new URL(url, window.location.href);
|
|
||||||
Object.entries(params).forEach(([k, v]) => result.searchParams.set(k, v));
|
|
||||||
return result.toString();
|
|
||||||
};
|
|
||||||
|
|
||||||
const j = (id: string): any | null => {
|
|
||||||
const elem = document.getElementById(id);
|
|
||||||
if (elem === null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return JSON.parse(elem.textContent);
|
|
||||||
};
|
|
||||||
|
|
||||||
const imageURL = (mood, cacheBuster, basePrefix) =>
|
|
||||||
u(`${basePrefix}/.within.website/x/cmd/anubis/static/img/${mood}.webp`, {
|
|
||||||
cacheBuster,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Detect available languages by loading the manifest
|
|
||||||
const getAvailableLanguages = async () => {
|
|
||||||
const basePrefix = j("anubis_base_prefix");
|
|
||||||
if (basePrefix === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
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"];
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.warn(
|
|
||||||
"Failed to load language manifest, falling back to default languages",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback to default languages if manifest loading fails
|
|
||||||
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;
|
|
||||||
|
|
||||||
// Load translations from JSON files
|
|
||||||
const loadTranslations = async (lang) => {
|
|
||||||
const basePrefix = j("anubis_base_prefix");
|
|
||||||
if (basePrefix === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const getRedirectUrl = () => {
|
|
||||||
const publicUrl = j("anubis_public_url");
|
|
||||||
if (publicUrl === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (publicUrl && window.location.href.startsWith(publicUrl)) {
|
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
|
||||||
return urlParams.get("redir");
|
|
||||||
}
|
|
||||||
return window.location.href;
|
|
||||||
};
|
|
||||||
|
|
||||||
let translations = {};
|
|
||||||
let currentLang;
|
|
||||||
|
|
||||||
// Initialize translations
|
|
||||||
const initTranslations = async () => {
|
|
||||||
currentLang = await getBrowserLanguage();
|
|
||||||
translations = await loadTranslations(currentLang);
|
|
||||||
};
|
|
||||||
|
|
||||||
const t = (key) => translations[`js_${key}`] || translations[key] || key;
|
|
||||||
|
|
||||||
(async () => {
|
|
||||||
// Initialize translations first
|
|
||||||
await initTranslations();
|
|
||||||
|
|
||||||
const dependencies = [
|
|
||||||
{
|
|
||||||
name: "Web Workers",
|
|
||||||
msg: t("web_workers_error"),
|
|
||||||
value: window.Worker,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Cookies",
|
|
||||||
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 anubisVersion = j("anubis_version");
|
|
||||||
const basePrefix = j("anubis_base_prefix");
|
|
||||||
const details = document.querySelector("details");
|
|
||||||
let userReadDetails = false;
|
|
||||||
|
|
||||||
if (details) {
|
|
||||||
details.addEventListener("toggle", () => {
|
|
||||||
if (details.open) {
|
|
||||||
userReadDetails = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const ohNoes = ({ titleMsg, statusMsg, imageSrc }) => {
|
|
||||||
title.innerHTML = titleMsg;
|
|
||||||
status.innerHTML = statusMsg;
|
|
||||||
image.src = imageSrc;
|
|
||||||
progress.style.display = "none";
|
|
||||||
};
|
|
||||||
|
|
||||||
status.innerHTML = t("calculating");
|
|
||||||
|
|
||||||
for (const { value, name, msg } of dependencies) {
|
|
||||||
if (!value) {
|
|
||||||
ohNoes({
|
|
||||||
titleMsg: `${t("missing_feature")} ${name}`,
|
|
||||||
statusMsg: msg,
|
|
||||||
imageSrc: imageURL("reject", anubisVersion, basePrefix),
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const { challenge, rules } = j("anubis_challenge");
|
|
||||||
|
|
||||||
const process = algorithms[rules.algorithm];
|
|
||||||
if (!process) {
|
|
||||||
ohNoes({
|
|
||||||
titleMsg: t("challenge_error"),
|
|
||||||
statusMsg: t("challenge_error_msg"),
|
|
||||||
imageSrc: imageURL("reject", anubisVersion, basePrefix),
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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`);
|
|
||||||
status.appendChild(rateText);
|
|
||||||
|
|
||||||
let lastSpeedUpdate = 0;
|
|
||||||
let showingApology = false;
|
|
||||||
const likelihood = Math.pow(16, -rules.difficulty);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const t0 = Date.now();
|
|
||||||
const { hash, nonce } = await process(
|
|
||||||
{ basePrefix, version: anubisVersion },
|
|
||||||
challenge.randomData,
|
|
||||||
rules.difficulty,
|
|
||||||
null,
|
|
||||||
(iters) => {
|
|
||||||
const delta = Date.now() - t0;
|
|
||||||
// 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`;
|
|
||||||
}
|
|
||||||
// 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
|
|
||||||
// apply a polynomial ease-out function to move faster in the beginning
|
|
||||||
// and then slow down as things get increasingly unlikely. quadratic felt
|
|
||||||
// the best in testing, but this may need adjustment in the future.
|
|
||||||
|
|
||||||
const probability = Math.pow(1 - likelihood, iters);
|
|
||||||
const distance = (1 - Math.pow(probability, 2)) * 100;
|
|
||||||
progress["aria-valuenow"] = distance;
|
|
||||||
if (progress.firstElementChild !== null) {
|
|
||||||
(progress.firstElementChild as HTMLElement).style.width =
|
|
||||||
`${distance}%`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (probability < 0.1 && !showingApology) {
|
|
||||||
status.append(
|
|
||||||
document.createElement("br"),
|
|
||||||
document.createTextNode(t("verification_longer")),
|
|
||||||
);
|
|
||||||
showingApology = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
const t1 = Date.now();
|
|
||||||
console.log({ hash, nonce });
|
|
||||||
|
|
||||||
if (userReadDetails) {
|
|
||||||
const container: HTMLDivElement = document.getElementById(
|
|
||||||
"progress",
|
|
||||||
) as HTMLDivElement;
|
|
||||||
|
|
||||||
// Style progress bar as a continue button
|
|
||||||
container.style.display = "flex";
|
|
||||||
container.style.alignItems = "center";
|
|
||||||
container.style.justifyContent = "center";
|
|
||||||
container.style.height = "2rem";
|
|
||||||
container.style.borderRadius = "1rem";
|
|
||||||
container.style.cursor = "pointer";
|
|
||||||
container.style.background = "#b16286";
|
|
||||||
container.style.color = "white";
|
|
||||||
container.style.fontWeight = "bold";
|
|
||||||
container.style.outline = "4px solid #b16286";
|
|
||||||
container.style.outlineOffset = "2px";
|
|
||||||
container.style.width = "min(20rem, 90%)";
|
|
||||||
container.style.margin = "1rem auto 2rem";
|
|
||||||
container.innerHTML = t("finished_reading");
|
|
||||||
|
|
||||||
function onDetailsExpand() {
|
|
||||||
const redir = getRedirectUrl();
|
|
||||||
window.location.replace(
|
|
||||||
u(`${basePrefix}/.within.website/x/cmd/anubis/api/pass-challenge`, {
|
|
||||||
id: challenge.id,
|
|
||||||
response: hash,
|
|
||||||
nonce,
|
|
||||||
redir,
|
|
||||||
elapsedTime: t1 - t0,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
container.onclick = onDetailsExpand;
|
|
||||||
setTimeout(onDetailsExpand, 30000);
|
|
||||||
} else {
|
|
||||||
const redir = getRedirectUrl();
|
|
||||||
window.location.replace(
|
|
||||||
u(`${basePrefix}/.within.website/x/cmd/anubis/api/pass-challenge`, {
|
|
||||||
id: challenge.id,
|
|
||||||
response: hash,
|
|
||||||
nonce,
|
|
||||||
redir,
|
|
||||||
elapsedTime: t1 - t0,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
ohNoes({
|
|
||||||
titleMsg: t("calculation_error"),
|
|
||||||
statusMsg: `${t("calculation_error_msg")} ${err.message}`,
|
|
||||||
imageSrc: imageURL("reject", anubisVersion, basePrefix),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
+336
@@ -0,0 +1,336 @@
|
|||||||
|
import { render } from "preact";
|
||||||
|
import { useState, useEffect, useRef } from "preact/hooks";
|
||||||
|
import algorithms from "./algorithms";
|
||||||
|
|
||||||
|
// from Xeact
|
||||||
|
const u = (url: string = "", params: Record<string, any> = {}) => {
|
||||||
|
let result = new URL(url, window.location.href);
|
||||||
|
Object.entries(params).forEach(([k, v]) => result.searchParams.set(k, v));
|
||||||
|
return result.toString();
|
||||||
|
};
|
||||||
|
|
||||||
|
const j = (id: string): any | null => {
|
||||||
|
const elem = document.getElementById(id);
|
||||||
|
if (elem === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const text = elem.textContent;
|
||||||
|
if (text == null || text.trim() === "") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSON.parse(text);
|
||||||
|
};
|
||||||
|
|
||||||
|
const imageURL = (
|
||||||
|
mood: string,
|
||||||
|
cacheBuster: string,
|
||||||
|
basePrefix: string,
|
||||||
|
): string =>
|
||||||
|
u(`${basePrefix}/.within.website/x/cmd/anubis/static/img/${mood}.webp`, {
|
||||||
|
cacheBuster,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// Load translations from JSON files
|
||||||
|
const loadTranslations = async (lang: string) => {
|
||||||
|
const basePrefix = j("anubis_base_prefix");
|
||||||
|
if (basePrefix === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getRedirectUrl = () => {
|
||||||
|
const publicUrl = j("anubis_public_url");
|
||||||
|
if (publicUrl === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (publicUrl && window.location.href.startsWith(publicUrl)) {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
return urlParams.get("redir");
|
||||||
|
}
|
||||||
|
return window.location.href;
|
||||||
|
};
|
||||||
|
|
||||||
|
let translations: Record<string, string> = {};
|
||||||
|
|
||||||
|
// Initialize translations
|
||||||
|
const initTranslations = async () => {
|
||||||
|
const currentLang = await getBrowserLanguage();
|
||||||
|
translations = await loadTranslations(currentLang);
|
||||||
|
};
|
||||||
|
|
||||||
|
const t = (key: string): string =>
|
||||||
|
translations[`js_${key}`] || translations[key] || key;
|
||||||
|
|
||||||
|
interface AppProps {
|
||||||
|
anubisVersion: string;
|
||||||
|
basePrefix: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function App({ anubisVersion, basePrefix }: AppProps) {
|
||||||
|
const [phase, setPhase] = useState<
|
||||||
|
"loading" | "computing" | "reading" | "error"
|
||||||
|
>("loading");
|
||||||
|
|
||||||
|
// Error info
|
||||||
|
const [errorTitle, setErrorTitle] = useState("");
|
||||||
|
const [errorMessage, setErrorMessage] = useState("");
|
||||||
|
const [errorImage, setErrorImage] = useState("");
|
||||||
|
|
||||||
|
// Computing info
|
||||||
|
const [difficulty, setDifficulty] = useState(0);
|
||||||
|
const [speed, setSpeed] = useState("0kH/s");
|
||||||
|
const [progress, setProgress] = useState(0);
|
||||||
|
const [showApology, setShowApology] = useState(false);
|
||||||
|
|
||||||
|
// Reading redirect callback
|
||||||
|
const redirectFn = useRef<(() => void) | null>(null);
|
||||||
|
const detailsRead = useRef(false);
|
||||||
|
|
||||||
|
// Sync <h1 id="title"> when entering error state (it's outside the Preact tree)
|
||||||
|
useEffect(() => {
|
||||||
|
if (phase === "error") {
|
||||||
|
const titleEl = document.getElementById("title");
|
||||||
|
if (titleEl) {
|
||||||
|
titleEl.textContent = errorTitle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [phase, errorTitle]);
|
||||||
|
|
||||||
|
// Main initialization
|
||||||
|
useEffect(() => {
|
||||||
|
const details = document.querySelector("details");
|
||||||
|
if (details) {
|
||||||
|
details.addEventListener("toggle", () => {
|
||||||
|
if (details.open) {
|
||||||
|
detailsRead.current = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const showError = (title: string, message: string, imageSrc: string) => {
|
||||||
|
setErrorTitle(title);
|
||||||
|
setErrorMessage(message);
|
||||||
|
setErrorImage(imageSrc);
|
||||||
|
setPhase("error");
|
||||||
|
};
|
||||||
|
|
||||||
|
const dependencies = [
|
||||||
|
{
|
||||||
|
name: "Web Workers",
|
||||||
|
msg: t("web_workers_error"),
|
||||||
|
value: window.Worker,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Cookies",
|
||||||
|
msg: t("cookies_error"),
|
||||||
|
value: navigator.cookieEnabled,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const { value, name, msg } of dependencies) {
|
||||||
|
if (!value) {
|
||||||
|
showError(
|
||||||
|
`${t("missing_feature")} ${name}`,
|
||||||
|
msg,
|
||||||
|
imageURL("reject", anubisVersion, basePrefix),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const challengeData = j("anubis_challenge");
|
||||||
|
if (!challengeData) {
|
||||||
|
showError(
|
||||||
|
t("challenge_error"),
|
||||||
|
t("challenge_data_missing"),
|
||||||
|
imageURL("reject", anubisVersion, basePrefix),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { challenge, rules } = challengeData;
|
||||||
|
|
||||||
|
const process = algorithms[rules.algorithm];
|
||||||
|
if (!process) {
|
||||||
|
showError(
|
||||||
|
t("challenge_error"),
|
||||||
|
t("challenge_error_msg"),
|
||||||
|
imageURL("reject", anubisVersion, basePrefix),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setPhase("computing");
|
||||||
|
setDifficulty(rules.difficulty);
|
||||||
|
|
||||||
|
const likelihood = Math.pow(16, -rules.difficulty);
|
||||||
|
let lastSpeedUpdate = 0;
|
||||||
|
let apologyShown = false;
|
||||||
|
const t0 = Date.now();
|
||||||
|
|
||||||
|
process(
|
||||||
|
{ basePrefix, version: anubisVersion },
|
||||||
|
challenge.randomData,
|
||||||
|
rules.difficulty,
|
||||||
|
null,
|
||||||
|
(iters: number) => {
|
||||||
|
const delta = Date.now() - t0;
|
||||||
|
// only update the speed every second so it's less visually distracting
|
||||||
|
if (delta - lastSpeedUpdate > 1000) {
|
||||||
|
lastSpeedUpdate = delta;
|
||||||
|
setSpeed(`${(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
|
||||||
|
// apply a polynomial ease-out function to move faster in the beginning
|
||||||
|
// and then slow down as things get increasingly unlikely. quadratic felt
|
||||||
|
// the best in testing, but this may need adjustment in the future.
|
||||||
|
|
||||||
|
const probability = Math.pow(1 - likelihood, iters);
|
||||||
|
const distance = (1 - Math.pow(probability, 2)) * 100;
|
||||||
|
setProgress(distance);
|
||||||
|
|
||||||
|
if (probability < 0.1 && !apologyShown) {
|
||||||
|
apologyShown = true;
|
||||||
|
setShowApology(true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.then((result: any) => {
|
||||||
|
const t1 = Date.now();
|
||||||
|
const { hash, nonce } = result;
|
||||||
|
console.log({ hash, nonce });
|
||||||
|
|
||||||
|
const doRedirect = () => {
|
||||||
|
const redir = getRedirectUrl();
|
||||||
|
window.location.replace(
|
||||||
|
u(`${basePrefix}/.within.website/x/cmd/anubis/api/pass-challenge`, {
|
||||||
|
id: challenge.id,
|
||||||
|
response: hash,
|
||||||
|
nonce,
|
||||||
|
redir,
|
||||||
|
elapsedTime: t1 - t0,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (detailsRead.current) {
|
||||||
|
redirectFn.current = doRedirect;
|
||||||
|
setPhase("reading");
|
||||||
|
setTimeout(doRedirect, 30000);
|
||||||
|
} else {
|
||||||
|
doRedirect();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err: Error) => {
|
||||||
|
showError(
|
||||||
|
t("calculation_error"),
|
||||||
|
`${t("calculation_error_msg")} ${err.message}`,
|
||||||
|
imageURL("reject", anubisVersion, basePrefix),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const pensiveURL = imageURL("pensive", anubisVersion, basePrefix);
|
||||||
|
|
||||||
|
if (phase === "error") {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<img style="width:100%;max-width:256px;" src={errorImage} />
|
||||||
|
<p id="status">{errorMessage}</p>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phase === "loading") {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<img style="width:100%;max-width:256px;" src={pensiveURL} />
|
||||||
|
<p id="status">{t("calculating")}</p>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// computing or reading
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<img style="width:100%;max-width:256px;" src={pensiveURL} />
|
||||||
|
<p id="status">
|
||||||
|
{`${t("calculating_difficulty")} ${difficulty}, `}
|
||||||
|
{`${t("speed")} ${speed}`}
|
||||||
|
{showApology && (
|
||||||
|
<>
|
||||||
|
<br />
|
||||||
|
{t("verification_longer")}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
{phase === "reading" ? (
|
||||||
|
<button
|
||||||
|
id="progress"
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
height: "2rem",
|
||||||
|
borderRadius: "1rem",
|
||||||
|
cursor: "pointer",
|
||||||
|
background: "#b16286",
|
||||||
|
color: "white",
|
||||||
|
fontWeight: "bold",
|
||||||
|
outline: "4px solid #b16286",
|
||||||
|
outlineOffset: "2px",
|
||||||
|
width: "min(20rem, 90%)",
|
||||||
|
margin: "1rem auto 2rem",
|
||||||
|
border: "none",
|
||||||
|
fontSize: "inherit",
|
||||||
|
fontFamily: "inherit",
|
||||||
|
}}
|
||||||
|
onClick={() => redirectFn.current?.()}
|
||||||
|
>
|
||||||
|
{t("finished_reading")}
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<div
|
||||||
|
id="progress"
|
||||||
|
role="progressbar"
|
||||||
|
aria-labelledby="status"
|
||||||
|
aria-valuenow={progress}
|
||||||
|
style={{ display: "inline-block" }}
|
||||||
|
>
|
||||||
|
<div class="bar-inner" style={{ width: `${progress}%` }}></div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bootstrap: init translations, then mount Preact
|
||||||
|
(async () => {
|
||||||
|
await initTranslations();
|
||||||
|
const anubisVersion = j("anubis_version");
|
||||||
|
const basePrefix = j("anubis_base_prefix");
|
||||||
|
const root = document.getElementById("app");
|
||||||
|
if (root) {
|
||||||
|
render(<App anubisVersion={anubisVersion} basePrefix={basePrefix} />, root);
|
||||||
|
}
|
||||||
|
})();
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2020",
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"jsxImportSource": "preact",
|
||||||
|
"noEmit": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": false
|
||||||
|
},
|
||||||
|
"include": ["js/**/*.ts", "js/**/*.tsx"]
|
||||||
|
}
|
||||||
@@ -12,8 +12,6 @@ import (
|
|||||||
"github.com/TecharoHQ/anubis/internal"
|
"github.com/TecharoHQ/anubis/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate go tool gosh ./build.sh
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
//go:embed *.css static
|
//go:embed *.css static
|
||||||
Static embed.FS
|
Static embed.FS
|
||||||
|
|||||||
Reference in New Issue
Block a user