mirror of
https://github.com/TecharoHQ/anubis.git
synced 2026-04-07 17:28:17 +00:00
Compare commits
12 Commits
Xe/proof-o
...
Xe/docker-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9499903715 | ||
|
|
31a654ecb6 | ||
|
|
492d9b374e | ||
|
|
1a4b5cadcb | ||
|
|
d5cdd21631 | ||
|
|
c81c21478a | ||
|
|
b0757a8b0e | ||
|
|
ca36cb091e | ||
|
|
b2b7183a8f | ||
|
|
0e0847cbeb | ||
|
|
00afa72c4b | ||
|
|
eb50f59351 |
25
.dockerignore
Normal file
25
.dockerignore
Normal file
@@ -0,0 +1,25 @@
|
||||
.env
|
||||
*.deb
|
||||
*.rpm
|
||||
|
||||
# Additional package locks
|
||||
pnpm-lock.yaml
|
||||
yarn.lock
|
||||
|
||||
# Go binaries and test artifacts
|
||||
main
|
||||
*.test
|
||||
|
||||
node_modules
|
||||
|
||||
# MacOS
|
||||
.DS_store
|
||||
|
||||
# Intellij
|
||||
.idea
|
||||
|
||||
# how does this get here
|
||||
doc/VERSION
|
||||
|
||||
web/static/js/*
|
||||
!web/static/js/.gitignore
|
||||
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: 'bug:'
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: 'feature:'
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
9
.github/ISSUE_TEMPLATE/security.md
vendored
Normal file
9
.github/ISSUE_TEMPLATE/security.md
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
name: Security report
|
||||
about: Do not file security reports here. Email security@techaro.lol.
|
||||
title: "security:"
|
||||
labels: ""
|
||||
assignees: Xe
|
||||
---
|
||||
|
||||
Do not file security reports here. Email security@techaro.lol.
|
||||
3
.github/actions/spelling/allow.txt
vendored
3
.github/actions/spelling/allow.txt
vendored
@@ -4,4 +4,5 @@ ssh
|
||||
ubuntu
|
||||
workarounds
|
||||
rjack
|
||||
msgbox
|
||||
msgbox
|
||||
xeact
|
||||
6
.github/actions/spelling/expect.txt
vendored
6
.github/actions/spelling/expect.txt
vendored
@@ -6,6 +6,7 @@ amazonbot
|
||||
anthro
|
||||
anubis
|
||||
anubistest
|
||||
apk
|
||||
Applebot
|
||||
archlinux
|
||||
asnc
|
||||
@@ -113,6 +114,7 @@ fsys
|
||||
fullchain
|
||||
gaissmai
|
||||
Galvus
|
||||
gcflags
|
||||
geoip
|
||||
geoipchecker
|
||||
gha
|
||||
@@ -215,6 +217,7 @@ NONINFRINGEMENT
|
||||
nosleep
|
||||
OCOB
|
||||
ogtag
|
||||
oklch
|
||||
omgili
|
||||
omgilibot
|
||||
openai
|
||||
@@ -267,6 +270,8 @@ runtimedirectory
|
||||
Ryzen
|
||||
sas
|
||||
sasl
|
||||
sbom
|
||||
screenshots
|
||||
searchbot
|
||||
searx
|
||||
sebest
|
||||
@@ -339,6 +344,7 @@ withthothmock
|
||||
wolfbeast
|
||||
wordpress
|
||||
Workaround
|
||||
workaround
|
||||
workdir
|
||||
wpbot
|
||||
XCircle
|
||||
|
||||
57
.github/workflows/docker-pr.yml
vendored
57
.github/workflows/docker-pr.yml
vendored
@@ -2,7 +2,7 @@ name: Docker image builds (pull requests)
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
branches: ["main"]
|
||||
|
||||
env:
|
||||
DOCKER_METADATA_SET_OUTPUT_ENV: "true"
|
||||
@@ -11,7 +11,7 @@ permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
buildx-bake:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout code
|
||||
@@ -21,48 +21,17 @@ jobs:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
|
||||
- name: Setup Homebrew cellar cache
|
||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
||||
with:
|
||||
path: |
|
||||
/home/linuxbrew/.linuxbrew/Cellar
|
||||
/home/linuxbrew/.linuxbrew/bin
|
||||
/home/linuxbrew/.linuxbrew/etc
|
||||
/home/linuxbrew/.linuxbrew/include
|
||||
/home/linuxbrew/.linuxbrew/lib
|
||||
/home/linuxbrew/.linuxbrew/opt
|
||||
/home/linuxbrew/.linuxbrew/sbin
|
||||
/home/linuxbrew/.linuxbrew/share
|
||||
/home/linuxbrew/.linuxbrew/var
|
||||
key: ${{ runner.os }}-go-homebrew-cellar-${{ hashFiles('go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-homebrew-cellar-
|
||||
|
||||
- name: Install Brew dependencies
|
||||
run: |
|
||||
brew bundle
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
|
||||
with:
|
||||
images: ghcr.io/${{ github.repository }}
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
||||
|
||||
- name: Build and push
|
||||
id: build
|
||||
run: |
|
||||
npm ci
|
||||
npm run container
|
||||
env:
|
||||
PULL_REQUEST_ID: ${{ github.event.number }}
|
||||
DOCKER_REPO: ghcr.io/${{ github.repository }}
|
||||
SLOG_LEVEL: debug
|
||||
|
||||
- run: |
|
||||
echo "Test this with:"
|
||||
echo "docker pull ${DOCKER_IMAGE}"
|
||||
env:
|
||||
DOCKER_IMAGE: ${{ steps.build.outputs.docker_image }}
|
||||
uses: docker/bake-action@76f9fa3a758507623da19f6092dc4089a7e61592 # v6.6.0
|
||||
with:
|
||||
source: .
|
||||
push: true
|
||||
sbom: true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
set: |
|
||||
anubis.tags=ttl.sh/techaro/pr-${{ github.event.number }}/anubis:24h
|
||||
|
||||
57
.github/workflows/docker.yml
vendored
57
.github/workflows/docker.yml
vendored
@@ -17,7 +17,7 @@ permissions:
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
buildx-bake:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout code
|
||||
@@ -27,33 +27,8 @@ jobs:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set lowercase image name
|
||||
run: |
|
||||
echo "IMAGE=ghcr.io/${GITHUB_REPOSITORY,,}" >> $GITHUB_ENV
|
||||
|
||||
- name: Set up Homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@main
|
||||
|
||||
- name: Setup Homebrew cellar cache
|
||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
||||
with:
|
||||
path: |
|
||||
/home/linuxbrew/.linuxbrew/Cellar
|
||||
/home/linuxbrew/.linuxbrew/bin
|
||||
/home/linuxbrew/.linuxbrew/etc
|
||||
/home/linuxbrew/.linuxbrew/include
|
||||
/home/linuxbrew/.linuxbrew/lib
|
||||
/home/linuxbrew/.linuxbrew/opt
|
||||
/home/linuxbrew/.linuxbrew/sbin
|
||||
/home/linuxbrew/.linuxbrew/share
|
||||
/home/linuxbrew/.linuxbrew/var
|
||||
key: ${{ runner.os }}-go-homebrew-cellar-${{ hashFiles('go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-homebrew-cellar-
|
||||
|
||||
- name: Install Brew dependencies
|
||||
run: |
|
||||
brew bundle
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
||||
|
||||
- name: Log into registry
|
||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
|
||||
@@ -62,24 +37,16 @@ jobs:
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
|
||||
with:
|
||||
images: ${{ env.IMAGE }}
|
||||
- name: Set version
|
||||
run: |
|
||||
echo "VERSION=$(git describe --tags --always --dirty) >> $GITHUB_ENV
|
||||
|
||||
- name: Build and push
|
||||
id: build
|
||||
run: |
|
||||
npm ci
|
||||
npm run container
|
||||
env:
|
||||
DOCKER_REPO: ${{ env.IMAGE }}
|
||||
SLOG_LEVEL: debug
|
||||
|
||||
- name: Generate artifact attestation
|
||||
uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2.4.0
|
||||
uses: docker/bake-action@76f9fa3a758507623da19f6092dc4089a7e61592 # v6.6.0
|
||||
with:
|
||||
subject-name: ${{ env.IMAGE }}
|
||||
subject-digest: ${{ steps.build.outputs.digest }}
|
||||
push-to-registry: true
|
||||
source: .
|
||||
push: true
|
||||
sbom: true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
@@ -211,6 +211,21 @@ thresholds:
|
||||
- weight >= 10
|
||||
- weight < 20
|
||||
action: CHALLENGE
|
||||
challenge:
|
||||
# https://anubis.techaro.lol/docs/admin/configuration/challenges/preact
|
||||
#
|
||||
# This challenge proves the client can run a webapp written with Preact.
|
||||
# The preact webapp simply loads, calculates the SHA-256 checksum of the
|
||||
# challenge data, and forwards that to the client.
|
||||
algorithm: preact
|
||||
difficulty: 1
|
||||
report_as: 1
|
||||
- name: mild-proof-of-work
|
||||
expression:
|
||||
all:
|
||||
- weight >= 20
|
||||
- weight < 30
|
||||
action: CHALLENGE
|
||||
challenge:
|
||||
# https://anubis.techaro.lol/docs/admin/configuration/challenges/proof-of-work
|
||||
algorithm: fast
|
||||
@@ -218,7 +233,7 @@ thresholds:
|
||||
report_as: 2
|
||||
# For clients that are browser like and have gained many points from custom rules
|
||||
- name: extreme-suspicion
|
||||
expression: weight >= 20
|
||||
expression: weight >= 30
|
||||
action: CHALLENGE
|
||||
challenge:
|
||||
# https://anubis.techaro.lol/docs/admin/configuration/challenges/proof-of-work
|
||||
|
||||
33
docker-bake.hcl
Normal file
33
docker-bake.hcl
Normal file
@@ -0,0 +1,33 @@
|
||||
variable "ALPINE_VERSION" { default = "3.22" }
|
||||
variable "GITHUB_SHA" { default = "devel" }
|
||||
variable "VERSION" { default = "devel-docker" }
|
||||
|
||||
group "default" {
|
||||
targets = [
|
||||
"anubis",
|
||||
]
|
||||
}
|
||||
|
||||
target "anubis" {
|
||||
args = {
|
||||
ALPINE_VERSION = "3.22"
|
||||
VERSION = "${VERSION}"
|
||||
}
|
||||
context = "."
|
||||
dockerfile = "./docker/anubis.Dockerfile"
|
||||
platforms = [
|
||||
"linux/386",
|
||||
"linux/amd64",
|
||||
"linux/arm64",
|
||||
"linux/arm/v7",
|
||||
"linux/ppc64le",
|
||||
"linux/riscv64",
|
||||
]
|
||||
pull = true
|
||||
sbom = true
|
||||
provenance = true
|
||||
tags = [
|
||||
"ghcr.io/techarohq/anubis:${VERSION}",
|
||||
"ghcr.io/techarohq/anubis:main"
|
||||
]
|
||||
}
|
||||
54
docker/anubis.Dockerfile
Normal file
54
docker/anubis.Dockerfile
Normal file
@@ -0,0 +1,54 @@
|
||||
ARG ALPINE_VERSION=edge
|
||||
FROM --platform=${BUILDPLATFORM} alpine:${ALPINE_VERSION} AS build
|
||||
|
||||
RUN apk -U add go nodejs git build-base git npm bash zstd brotli gzip
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY go.mod go.sum ./
|
||||
RUN \
|
||||
--mount=type=cache,target=/root/.cache \
|
||||
--mount=type=cache,target=/root/go \
|
||||
go mod download
|
||||
|
||||
COPY package.json package-lock.json ./
|
||||
RUN \
|
||||
--mount=type=cache,target=/app/node_modules \
|
||||
npm ci
|
||||
|
||||
COPY . .
|
||||
RUN \
|
||||
--mount=type=cache,target=/root/.cache \
|
||||
--mount=type=cache,target=/root/go \
|
||||
--mount=type=cache,target=/app/node_modules \
|
||||
npm run assets
|
||||
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
ARG VERSION=devel-docker
|
||||
|
||||
RUN \
|
||||
--mount=type=cache,target=/root/.cache \
|
||||
--mount=type=cache,target=/root/go \
|
||||
--mount=type=cache,target=/app/node_modules \
|
||||
GOOS=${TARGETOS} \
|
||||
GOARCH=${TARGETARCH} \
|
||||
CGO_ENABLED=0 \
|
||||
GOARM=7 \
|
||||
go build \
|
||||
-gcflags "all=-N -l" \
|
||||
-o /app/bin/anubis \
|
||||
-ldflags "-s -w -extldflags -static -X github.com/TecharoHQ/anubis.Version=${VERSION}" \
|
||||
./cmd/anubis
|
||||
|
||||
FROM alpine:${ALPINE_VERSION} AS run
|
||||
WORKDIR /app
|
||||
|
||||
RUN apk -U add ca-certificates mailcap
|
||||
|
||||
COPY --from=build /app/bin/anubis /app/bin/anubis
|
||||
|
||||
CMD ["/app/bin/anubis"]
|
||||
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 CMD [ "/app/bin/anubis", "--healthcheck" ]
|
||||
|
||||
LABEL org.opencontainers.image.source="https://github.com/TecharoHQ/anubis"
|
||||
@@ -315,3 +315,52 @@
|
||||
gap: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
.block {
|
||||
background-color: oklch(93% 0.034 272.788);
|
||||
}
|
||||
|
||||
.challengeText {
|
||||
color: oklch(12.9% 0.042 264.695);
|
||||
}
|
||||
|
||||
.combinedDataText {
|
||||
color: oklch(12.9% 0.042 264.695);
|
||||
}
|
||||
|
||||
.nonceButton {
|
||||
background-color: oklch(88.2% 0.059 254.128);
|
||||
}
|
||||
|
||||
.nonceValue {
|
||||
color: oklch(12.9% 0.042 264.695);
|
||||
}
|
||||
|
||||
.blockTitle {
|
||||
color: oklch(45% 0.085 224.283);
|
||||
}
|
||||
|
||||
.hashContainerSuccess {
|
||||
background-color: oklch(95% 0.052 163.051);
|
||||
border-color: rgb(74 222 128);
|
||||
}
|
||||
|
||||
.hashContainerError {
|
||||
background-color: oklch(94.1% 0.03 12.58);
|
||||
border-color: rgb(248 113 113);
|
||||
}
|
||||
|
||||
.hashPrefixGreen {
|
||||
color: oklch(53.2% 0.157 131.589);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.hashPrefixRed {
|
||||
color: oklch(45.5% 0.188 13.697);
|
||||
}
|
||||
|
||||
.hashSuffix {
|
||||
color: oklch(27.9% 0.041 260.031);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,12 +7,13 @@ sidebar_position: 999
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).https://bsky.app/profile/xeiaso.net/post/3lxkqbd25hk22
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
<!-- This changes the project to: -->
|
||||
|
||||
- Add a "proof of React" challenge to prove that the client is able to run a simple JSX app.
|
||||
- Added possibility to disable HTTP keep-alive to support backends not properly
|
||||
handling it
|
||||
- Added a missing link to the Caddy installation environment in the installation documentation.
|
||||
@@ -67,8 +68,18 @@ Thanks to [@taviso](https://github.com/taviso) for reporting this issue.
|
||||
|
||||
### Breaking changes
|
||||
|
||||
We try to introduce breaking changes as much as possible, but these are the changes that may be relevant for you as an administrator:
|
||||
|
||||
- The "slow" frontend solver has been removed in order to reduce maintenance burden. Any existing uses of it will still work, but issue a warning upon startup asking administrators to upgrade to the "fast" frontend solver.
|
||||
|
||||
#### Docker image build process has been changed
|
||||
|
||||
Previously Docker images were built with [ko](https://ko.build/), which put the Anubis binary at `/ko-app/anubis`. [#862](https://github.com/TecharoHQ/anubis/pull/862) changes this to build with [docker buildx bake](https://docs.docker.com/reference/cli/docker/buildx/bake/) instead. If this causes you problems, please [file an issue](https://github.com/TecharoHQ/anubis/issues/new).
|
||||
|
||||
### New Locales
|
||||
|
||||
- [Lithuanian](https://github.com/TecharoHQ/anubis/pull/972)
|
||||
|
||||
## v1.21.3: Minfilia Warde - Echo 3
|
||||
|
||||
### Added
|
||||
|
||||
19
docs/docs/admin/configuration/challenges/preact.mdx
Normal file
19
docs/docs/admin/configuration/challenges/preact.mdx
Normal file
@@ -0,0 +1,19 @@
|
||||
# Preact
|
||||
|
||||
The `preact` challenge sends the browser a simple challenge that makes it run very lightweight JavaScript that proves the client is able to execute client-side JavaScript. It uses [Preact](https://www.npmjs.com/package/preact) (a lightweight client side web framework in the vein of React) to do this.
|
||||
|
||||
To use it in your Anubis configuration:
|
||||
|
||||
```yaml
|
||||
# Generic catchall rule
|
||||
- name: generic-browser
|
||||
user_agent_regex: >-
|
||||
Mozilla|Opera
|
||||
action: CHALLENGE
|
||||
challenge:
|
||||
difficulty: 1 # Number of seconds to wait before refreshing the page
|
||||
report_as: 4 # Unused by this challenge method
|
||||
algorithm: preact
|
||||
```
|
||||
|
||||
This is the default challenge method for most clients.
|
||||
@@ -36,6 +36,7 @@ import (
|
||||
|
||||
// challenge implementations
|
||||
_ "github.com/TecharoHQ/anubis/lib/challenge/metarefresh"
|
||||
_ "github.com/TecharoHQ/anubis/lib/challenge/preact"
|
||||
_ "github.com/TecharoHQ/anubis/lib/challenge/proofofwork"
|
||||
)
|
||||
|
||||
|
||||
49
lib/challenge/preact/build.sh
Executable file
49
lib/challenge/preact/build.sh
Executable file
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
LICENSE='/*
|
||||
@licstart The following is the entire license notice for the
|
||||
JavaScript code in this page.
|
||||
|
||||
Copyright (c) 2025 Xe Iaso <xe.iaso@techaro.lol>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
Includes code from https://www.npmjs.com/package/preact which is used under
|
||||
the terms of the MIT license.
|
||||
|
||||
Includes code from https://github.com/aws/aws-sdk-js-crypto-helpers which is
|
||||
used under the terms of the Apache 2 license.
|
||||
|
||||
@licend The above is the entire license notice
|
||||
for the JavaScript code in this page.
|
||||
*/'
|
||||
|
||||
mkdir -p static/js
|
||||
|
||||
for file in js/*.jsx; do
|
||||
filename="${file##*/}" # Extracts "app.jsx" from "./js/app.jsx"
|
||||
output="${filename%.jsx}.js" # Changes "app.jsx" to "app.js"
|
||||
echo $output
|
||||
|
||||
esbuild "${file}" --minify --bundle --outfile=static/"${output}" --banner:js="${LICENSE}"
|
||||
done
|
||||
62
lib/challenge/preact/js/app.jsx
Normal file
62
lib/challenge/preact/js/app.jsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import { render, h, Fragment } from 'preact';
|
||||
import { useState, useEffect } from 'preact/hooks';
|
||||
import { g, j, u, x } from "./xeact.js";
|
||||
import { Sha256 } from '@aws-crypto/sha256-js';
|
||||
|
||||
/** @jsx h */
|
||||
/** @jsxFrag Fragment */
|
||||
|
||||
function toHexString(arr) {
|
||||
return Array.from(arr)
|
||||
.map((c) => c.toString(16).padStart(2, "0"))
|
||||
.join("");
|
||||
}
|
||||
|
||||
const App = () => {
|
||||
const [state, setState] = useState(null);
|
||||
const [imageURL, setImageURL] = useState(null);
|
||||
const [passed, setPassed] = useState(false);
|
||||
const [challenge, setChallenge] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
setState(j("preact_info"));
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setImageURL(state.pensive_url);
|
||||
const hash = new Sha256('');
|
||||
hash.update(state.challenge);
|
||||
setChallenge(toHexString(hash.digestSync()));
|
||||
}, [state]);
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => {
|
||||
setPassed(true);
|
||||
}, state.difficulty * 100);
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}, [challenge]);
|
||||
|
||||
useEffect(() => {
|
||||
window.location.href = u(state.redir, {
|
||||
result: challenge,
|
||||
});
|
||||
}, [passed]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{imageURL !== null && (
|
||||
<img src={imageURL} style="width:100%;max-width:256px;" />
|
||||
)}
|
||||
{state !== null && (
|
||||
<>
|
||||
<p id="status">{state.loading_message}</p>
|
||||
<p>{state.connection_security_message}</p>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
x(g("app"));
|
||||
render(<App />, g("app"));
|
||||
129
lib/challenge/preact/js/xeact.js
Normal file
129
lib/challenge/preact/js/xeact.js
Normal file
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
* Creates a DOM element, assigns the properties of `data` to it, and appends all `children`.
|
||||
*
|
||||
* @type{function(string|Function, Object=, Node|Array.<Node|string>=)}
|
||||
*/
|
||||
const h = (name, data = {}, children = []) => {
|
||||
const result =
|
||||
typeof name == "function" ? name(data) : Object.assign(document.createElement(name), data);
|
||||
if (!Array.isArray(children)) {
|
||||
children = [children];
|
||||
}
|
||||
result.append(...children);
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a text node.
|
||||
*
|
||||
* Equivalent to `document.createTextNode(text)`
|
||||
*
|
||||
* @type{function(string): Text}
|
||||
*/
|
||||
const t = (text) => document.createTextNode(text);
|
||||
|
||||
/**
|
||||
* Remove all child nodes from a DOM element.
|
||||
*
|
||||
* @type{function(Node)}
|
||||
*/
|
||||
const x = (elem) => {
|
||||
while (elem.lastChild) {
|
||||
elem.removeChild(elem.lastChild);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get all elements with the given ID.
|
||||
*
|
||||
* Equivalent to `document.getElementById(name)`
|
||||
*
|
||||
* @type{function(string): HTMLElement}
|
||||
*/
|
||||
const g = (name) => document.getElementById(name);
|
||||
|
||||
/**
|
||||
* Get all elements with the given class name.
|
||||
*
|
||||
* Equivalent to `document.getElementsByClassName(name)`
|
||||
*
|
||||
* @type{function(string): HTMLCollectionOf.<Element>}
|
||||
*/
|
||||
const c = (name) => document.getElementsByClassName(name);
|
||||
|
||||
/** @type{function(string): HTMLCollectionOf.<Element>} */
|
||||
const n = (name) => document.getElementsByName(name);
|
||||
|
||||
/**
|
||||
* Get all elements matching the given HTML selector.
|
||||
*
|
||||
* Matches selectors with `document.querySelectorAll(selector)`
|
||||
*
|
||||
* @type{function(string): Array.<HTMLElement>}
|
||||
*/
|
||||
const s = (selector) => Array.from(document.querySelectorAll(selector));
|
||||
|
||||
/**
|
||||
* Generate a relative URL from `url`, appending all key-value pairs from `params` as URL-encoded parameters.
|
||||
*
|
||||
* @type{function(string=, Object=): string}
|
||||
*/
|
||||
const u = (url = "", params = {}) => {
|
||||
let result = new URL(url, window.location.href);
|
||||
Object.entries(params).forEach((kv) => {
|
||||
let [k, v] = kv;
|
||||
result.searchParams.set(k, v);
|
||||
});
|
||||
return result.toString();
|
||||
};
|
||||
|
||||
/**
|
||||
* Takes a callback to run when all DOM content is loaded.
|
||||
*
|
||||
* Equivalent to `window.addEventListener('DOMContentLoaded', callback)`
|
||||
*
|
||||
* @type{function(function())}
|
||||
*/
|
||||
const r = (callback) => window.addEventListener("DOMContentLoaded", callback);
|
||||
|
||||
/**
|
||||
* Allows a stateful value to be tracked by consumers.
|
||||
*
|
||||
* This is the Xeact version of the React useState hook.
|
||||
*
|
||||
* @type{function(any): [function(): any, function(any): void]}
|
||||
*/
|
||||
const useState = (value = undefined) => {
|
||||
return [
|
||||
() => value,
|
||||
(x) => {
|
||||
value = x;
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
/**
|
||||
* Debounce an action for up to ms milliseconds.
|
||||
*
|
||||
* @type{function(number): function(function(any): void)}
|
||||
*/
|
||||
const d = (ms) => {
|
||||
let debounceTimer = null;
|
||||
return (f) => {
|
||||
clearTimeout(debounceTimer);
|
||||
debounceTimer = setTimeout(f, ms);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the contents of a given HTML page element as JSON and
|
||||
* return the results.
|
||||
*
|
||||
* This is useful when using templ to pass complicated data from
|
||||
* the server to the client via HTML[1].
|
||||
*
|
||||
* [1]: https://templ.guide/syntax-and-usage/script-templates/#pass-server-side-data-to-the-client-in-a-html-attribute
|
||||
*/
|
||||
const j = (id) => JSON.parse(g(id).textContent);
|
||||
|
||||
export { h, t, x, g, j, c, n, u, s, r, useState, d };
|
||||
74
lib/challenge/preact/preact.go
Normal file
74
lib/challenge/preact/preact.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package preact
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/subtle"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/TecharoHQ/anubis"
|
||||
"github.com/TecharoHQ/anubis/internal"
|
||||
"github.com/TecharoHQ/anubis/lib/challenge"
|
||||
"github.com/TecharoHQ/anubis/lib/localization"
|
||||
"github.com/a-h/templ"
|
||||
)
|
||||
|
||||
//go:generate ./build.sh
|
||||
//go:generate go tool github.com/a-h/templ/cmd/templ generate
|
||||
|
||||
//go:embed static/app.js
|
||||
var appJS []byte
|
||||
|
||||
func renderAppJS(ctx context.Context, out io.Writer) error {
|
||||
fmt.Fprint(out, `<script type="module">`)
|
||||
out.Write(appJS)
|
||||
fmt.Fprint(out, "</script>")
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
challenge.Register("preact", &impl{})
|
||||
}
|
||||
|
||||
type impl struct{}
|
||||
|
||||
func (i *impl) Setup(mux *http.ServeMux) {}
|
||||
|
||||
func (i *impl) Issue(r *http.Request, lg *slog.Logger, in *challenge.IssueInput) (templ.Component, error) {
|
||||
u, err := r.URL.Parse(anubis.BasePrefix + "/.within.website/x/cmd/anubis/api/pass-challenge")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't render page: %w", err)
|
||||
}
|
||||
|
||||
q := u.Query()
|
||||
q.Set("redir", r.URL.String())
|
||||
q.Set("id", in.Challenge.ID)
|
||||
u.RawQuery = q.Encode()
|
||||
|
||||
loc := localization.GetLocalizer(r)
|
||||
|
||||
result := page(u.String(), in.Challenge.RandomData, in.Rule.Challenge.Difficulty, loc)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (i *impl) Validate(r *http.Request, lg *slog.Logger, in *challenge.ValidateInput) error {
|
||||
wantTime := in.Challenge.IssuedAt.Add(time.Duration(in.Rule.Challenge.Difficulty) * 95 * time.Millisecond)
|
||||
|
||||
if time.Now().Before(wantTime) {
|
||||
return challenge.NewError("validate", "insufficent time", fmt.Errorf("%w: wanted user to wait until at least %s", challenge.ErrFailed, wantTime.Format(time.RFC3339)))
|
||||
}
|
||||
|
||||
got := r.FormValue("result")
|
||||
want := internal.SHA256sum(in.Challenge.RandomData)
|
||||
|
||||
if subtle.ConstantTimeCompare([]byte(want), []byte(got)) != 1 {
|
||||
return challenge.NewError("validate", "invalid response", fmt.Errorf("%w: wanted response %s but got %s", challenge.ErrFailed, want, got))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
28
lib/challenge/preact/preact.templ
Normal file
28
lib/challenge/preact/preact.templ
Normal file
@@ -0,0 +1,28 @@
|
||||
package preact
|
||||
|
||||
import (
|
||||
"github.com/TecharoHQ/anubis"
|
||||
"github.com/TecharoHQ/anubis/lib/localization"
|
||||
)
|
||||
|
||||
templ page(redir, challenge string, difficulty int, loc *localization.SimpleLocalizer) {
|
||||
<div class="centered-div">
|
||||
<div id="app">
|
||||
<img id="image" style="width:100%;max-width:256px;" src={ anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/img/pensive.webp?cacheBuster=" + anubis.Version }/>
|
||||
<p id="status">{ loc.T("loading") }</p>
|
||||
<p>{ loc.T("connection_security") }</p>
|
||||
</div>
|
||||
@templ.JSONScript("preact_info", map[string]any{
|
||||
"redir": redir,
|
||||
"challenge": challenge,
|
||||
"difficulty": difficulty,
|
||||
"connection_security_message": loc.T("connection_security"),
|
||||
"loading_message": loc.T("loading"),
|
||||
"pensive_url": anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/img/pensive.webp?cacheBuster=" + anubis.Version,
|
||||
})
|
||||
@templ.ComponentFunc(renderAppJS)
|
||||
<noscript>
|
||||
{ loc.T("javascript_required") }
|
||||
</noscript>
|
||||
</div>
|
||||
}
|
||||
116
lib/challenge/preact/preact_templ.go
generated
Normal file
116
lib/challenge/preact/preact_templ.go
generated
Normal file
@@ -0,0 +1,116 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.3.924
|
||||
package preact
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import (
|
||||
"github.com/TecharoHQ/anubis"
|
||||
"github.com/TecharoHQ/anubis/lib/localization"
|
||||
)
|
||||
|
||||
func page(redir, challenge string, difficulty int, loc *localization.SimpleLocalizer) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"centered-div\"><div id=\"app\"><img id=\"image\" style=\"width:100%;max-width:256px;\" src=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
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)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `preact.templ`, Line: 11, Col: 166}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\"><p id=\"status\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(loc.T("loading"))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `preact.templ`, Line: 12, Col: 36}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</p><p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(loc.T("connection_security"))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `preact.templ`, Line: 13, Col: 36}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "</p></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ.JSONScript("preact_info", map[string]any{
|
||||
"redir": redir,
|
||||
"challenge": challenge,
|
||||
"difficulty": difficulty,
|
||||
"connection_security_message": loc.T("connection_security"),
|
||||
"loading_message": loc.T("loading"),
|
||||
"pensive_url": anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/img/pensive.webp?cacheBuster=" + anubis.Version,
|
||||
}).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ.ComponentFunc(renderAppJS).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<noscript>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(loc.T("javascript_required"))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `preact.templ`, Line: 25, Col: 33}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "</noscript></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
1
lib/challenge/preact/static/.gitignore
vendored
Normal file
1
lib/challenge/preact/static/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
app.js
|
||||
65
lib/localization/locales/lt.json
Normal file
65
lib/localization/locales/lt.json
Normal file
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"loading": "Įkeliama...",
|
||||
"why_am_i_seeing": "Kodėl tai matau?",
|
||||
"protected_by": "Saugo",
|
||||
"protected_from": "iš",
|
||||
"made_with": "Sukurta 🇨🇦 su ❤️",
|
||||
"mascot_design": "Talismao dizainą sukūrė",
|
||||
"ai_companies_explanation": "Šią užsklandą matote, nes šią svetainę administruojantis asmuo įdiegė ir sukonfigūravo „Anubis“, siekdamas apsaugoti svetainę nuo DI kompanijų robotų, agresyviai siurbiančių visą svetainių turinį. Neretai toks elgesys sukelia svetainių veikimo trikdžius, todėl jos tampa nepasiekiamos niekam.",
|
||||
"anubis_compromise": "„Anubis“ – tai kompromisas. „Anubis“ naudoja „darbo įrodymo“ (angl. „Proof-of-Work“) metodą, panašų į „Hashcash“ – anksčiau siūlytą „darbo įrodymo“ principu pagrįstą apsaugą el. paštui. Šio sumanymo pagrindinė idėja paprasta: paprastiems lankytojams toks papildomas krūvis yra nežymus, tuo tarpu masiškai duomenis siurbiantiems robotams jis greitai pasijunta ir stipriai pabrangina siurbimą.",
|
||||
"hack_purpose": "Vis dėlto, šis metodas laikytinas tik laikinu tarpiniu sprendimu, suteikiančiu galimybę skirti daugiau laiko atrasti robotizuotų naršyklių ypatybėms (pavyzdžiui, šriftų atvaizdavimo savitumams), siekiant iššūkio „darbo įrodymu“ tinklalapį tiems naudotojams, kurie atrodo tikri, rodyti kuo rečiau.",
|
||||
"simplified_explanation": "Tai – priemonė prieš robotus ir piktybines užklausas, panaši į „CAPTCHA“. Tačiau šiuo atveju užduotį turite atlikti ne jūs, o jūsų naršyklė, kuriai išspręsti pateikiama matematinė užduotis. Šis metodas vadinamas „darbo įrodymu“ (angl. <a href=\"https://en.wikipedia.org/wiki/Proof_of_work\">„Proof-of-work“</a>). Naršyklė atsakymą paprastai apskaičiuoja per kelias sekundes, o tuomet jums suteikiama prieiga prie svetainės. Dėkojame jums už supratingumą ir kantrybę.",
|
||||
"jshelter_note": "Turėkite omenyje, jog „Anubis“ reikalauja šiuolaikinių „JavaScript“ funkcijų, kurias tam tikri naršyklių įskiepiai, pavyzdžiui, „JShelter“, gali atjungti. Norint naršyti šią svetainę, teks joje „JShelter“ ar kitus analogiškus įskiepius atjungti.",
|
||||
"version_info": "Šioje svetainėje veikia „Anubis“ versija",
|
||||
"try_again": "Bandyti dar kartą",
|
||||
"go_home": "Grįžkite į pradžią",
|
||||
"contact_webmaster": "arba, jei manote, jog esate blokuojami per klaidą, kreipkitės į svetainės administratorių adresu",
|
||||
"connection_security": "Prašom luktelėti, kol patikrinsime jūsų ryšio saugumą.",
|
||||
"javascript_required": "Deja, kad galėtumėte praeiti pro šią užsklandą, naršyklėje turėsite įjungti „JavaScript“. Tai reikalinga, nes DI produktus kuriančios įmonės visiškai nepaiso saityne nusistovėjusios naudojimosi svetainėmis tvarkos (etiketo). Sprendimas, kuriam nebūtinas įjungtas „JavaScript“, šiuo metu kuriamas.",
|
||||
"benchmark_requires_js": "Įvertinimo įrankiui būtina, kad naršyklėje būtų įjungtas „JavaScript“ palaikymas.",
|
||||
"difficulty": "Sudėtingumas:",
|
||||
"algorithm": "Algoritmas:",
|
||||
"compare": "Palyginti:",
|
||||
"time": "Laikas",
|
||||
"iters": "Iteracijos",
|
||||
"time_a": "Laikas A",
|
||||
"iters_a": "Iteracijos A",
|
||||
"time_b": "Laikas B",
|
||||
"iters_b": "Iteracijos B",
|
||||
"static_check_endpoint": "Tai – tik būsenos patikrinimo adresas, kurį gali naudoti jūsų atvirkštinis įgaliotasis serveris.",
|
||||
"authorization_required": "Būtinas leidimas",
|
||||
"cookies_disabled": "Jūsų naršyklė sukonfigūruota nepriimti slapukų. „Anubis“ veikimui – siekiant užtikrinti, jog jūs esate tikras asmuo, būtini funkciniai (teisėto intereso) slapukai. Prašom leisti slapukus šioje svetainėje",
|
||||
"access_denied": "Prieiga uždrausta: klaidos kodas",
|
||||
"dronebl_entry": "„DroneBL“ pranešė apie įrašą",
|
||||
"see_dronebl_lookup": "parodyti",
|
||||
"internal_server_error": "Saityno serverio klaida: administratorius netinkamai sukonfigūravo „Anubis“ užsklandą. Susisiekite su svetainės administratoriumi ir paprašykite, kad paskaitytų žurnalų įrašus",
|
||||
"invalid_redirect": "Netinkamas nukreipimas",
|
||||
"redirect_not_parseable": "Nukreipimo adreso nepavyko išanalizuoti",
|
||||
"redirect_domain_not_allowed": "Nukreipimo domenas neleistinas",
|
||||
"failed_to_sign_jwt": "nepavyko pasirašyti JWT",
|
||||
"invalid_invocation": "Netinkamas kreipinys į „MakeChallenge“",
|
||||
"client_error_browser": "Kliento klaida: įsitikinkite, jog jūsų naršyklė pakankamai atšviežinta ir bandykite dar kartą.",
|
||||
"oh_noes": "O, ne!",
|
||||
"benchmarking_anubis": "„Anubis“ vertina!",
|
||||
"you_are_not_a_bot": "Jūs nesate robotas!",
|
||||
"making_sure_not_bot": "Stengiamasi užtikrinti, jog jūs nesate robotas!",
|
||||
"celphase": "CELPHASE",
|
||||
"js_web_crypto_error": "Jūsų naršyklėje nėra funkcionalaus „web.crypto“ elemento. Ar jūs šį tinklalapį žiūrite iš saugaus konteksto?",
|
||||
"js_web_workers_error": "Jūsų naršyklė nepalaiko aptarnavimo scenarijų, kuriuos „Anubis“ naudoja išvengti naršyklės strigčių. Gal turite įdiegtą „JShelter“ ar panašų įskiepį?",
|
||||
"js_cookies_error": "Jūsų naršyklė nepriima slapukų. „Anubis“ iššūkį jau praėjusius lankytojus atskiria pagal prieigos raktą, kurį įrašo slapuke. Prašom įjungti slapukus šiai svetainei. „Anubis“ slapuko pavadinimas gali kisti be įspėjimo. Slapuko pavadinimas ir reikšmė nėra viešosios programavimo sąsajos dalis.",
|
||||
"js_context_not_secure": "Jūsų kontekstas nėra saugus!",
|
||||
"js_context_not_secure_msg": "Pabandykite prisijungti per HTTPS arba praneškite svetainės administratoriui, kad sukonfigūruotų HTTPS. Išsamesnės informacijos rasite <a href=\"https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts#when_is_a_context_considered_secure\">MDN</a> (anglų k.).",
|
||||
"js_calculating": "Skaičiuojama...",
|
||||
"js_missing_feature": "Trūksta funkcionalumo",
|
||||
"js_challenge_error": "Iššūkio klaida!",
|
||||
"js_challenge_error_msg": "Nepavyko nustatyti patikros algoritmo. Pamėginkite įkelti tinklalapį iš naujo.",
|
||||
"js_calculating_difficulty": "Skaičiuojama...<br/>Sudėtingumas:",
|
||||
"js_speed": "Sparta:",
|
||||
"js_verification_longer": "Patikra užtrunka ilgiau nei įprasta. Neskubėkite įkelti šio tinklalapio iš naujo.",
|
||||
"js_success": "Sėkmė!",
|
||||
"js_done_took": "Baigta! Prireikė",
|
||||
"js_iterations": "iteracijų",
|
||||
"js_finished_reading": "Viską perskaičiau, tęskime →",
|
||||
"js_calculation_error": "Skaičiavimo klaida!",
|
||||
"js_calculation_error_msg": "Nepavyko įveikti iššūkio:"
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
"is",
|
||||
"it",
|
||||
"ja",
|
||||
"lt",
|
||||
"nb",
|
||||
"nl",
|
||||
"nn",
|
||||
|
||||
13
package-lock.json
generated
13
package-lock.json
generated
@@ -9,7 +9,8 @@
|
||||
"version": "1.22.0-pre1",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@aws-crypto/sha256-js": "^5.2.0"
|
||||
"@aws-crypto/sha256-js": "^5.2.0",
|
||||
"preact": "^10.27.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cssnano": "^7.1.1",
|
||||
@@ -2326,6 +2327,16 @@
|
||||
"postcss": "^8.4.32"
|
||||
}
|
||||
},
|
||||
"node_modules/preact": {
|
||||
"version": "10.27.1",
|
||||
"resolved": "https://registry.npmjs.org/preact/-/preact-10.27.1.tgz",
|
||||
"integrity": "sha512-V79raXEWch/rbqoNc7nT9E4ep7lu+mI3+sBmfRD4i1M73R3WLYcCtdI0ibxGVf4eQL8ZIz2nFacqEC+rmnOORQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/preact"
|
||||
}
|
||||
},
|
||||
"node_modules/pretty-hrtime": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"postcss-url": "^10.1.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-crypto/sha256-js": "^5.2.0"
|
||||
"@aws-crypto/sha256-js": "^5.2.0",
|
||||
"preact": "^10.27.1"
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ services:
|
||||
- ./var/repos:/srv/git
|
||||
|
||||
anubis:
|
||||
image: ko.local/anubis
|
||||
image: ghcr.io/techarohq/anubis:devel-docker
|
||||
environment:
|
||||
BIND: ":8005"
|
||||
TARGET: http://cgit:80
|
||||
|
||||
@@ -9,7 +9,7 @@ set -u
|
||||
|
||||
(
|
||||
cd ../.. && \
|
||||
ko build --platform=all --base-import-paths --tags="latest" --image-user=1000 --image-annotation="" --image-label="" ./cmd/anubis -L
|
||||
docker buildx bake
|
||||
)
|
||||
|
||||
rm -rf ./var/repos ./var/clones
|
||||
|
||||
@@ -9,9 +9,10 @@ set -u
|
||||
|
||||
(
|
||||
cd ../.. && \
|
||||
ko build --platform=all --base-import-paths --tags="latest" --image-user=1000 --image-annotation="" --image-label="" ./cmd/anubis -L
|
||||
docker buildx bake
|
||||
)
|
||||
|
||||
|
||||
rm -rf ./var/repos ./var/foo
|
||||
mkdir -p ./var/repos
|
||||
|
||||
|
||||
@@ -9,9 +9,10 @@ set -u
|
||||
|
||||
(
|
||||
cd ../.. && \
|
||||
ko build --platform=all --base-import-paths --tags="latest" --image-user=1000 --image-annotation="" --image-label="" ./cmd/anubis -L
|
||||
docker buildx bake
|
||||
)
|
||||
|
||||
|
||||
docker compose up -d
|
||||
|
||||
attempt=1
|
||||
|
||||
@@ -17,16 +17,7 @@ function build_anubis_ko() {
|
||||
cd $REPO_ROOT && npm ci && npm run assets
|
||||
)
|
||||
(
|
||||
cd $REPO_ROOT &&
|
||||
VERSION=devel ko build \
|
||||
--platform=all \
|
||||
--base-import-paths \
|
||||
--tags="latest" \
|
||||
--image-user=1000 \
|
||||
--image-annotation="" \
|
||||
--image-label="" \
|
||||
./cmd/anubis \
|
||||
--local
|
||||
cd $REPO_ROOT && docker buildx bake
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user