diff options
28 files changed, 221 insertions, 75 deletions
diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml index 8461366..b124f75 100644 --- a/.github/workflows/docker-pr.yml +++ b/.github/workflows/docker-pr.yml @@ -20,11 +20,29 @@ jobs: fetch-tags: true fetch-depth: 0 - - uses: actions/setup-go@v5 + - name: Set up Homebrew + uses: Homebrew/actions/setup-homebrew@master + + - name: Setup Homebrew cellar cache + uses: actions/cache@v4 with: - go-version: '1.24.x' + 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- - - uses: ko-build/setup-ko@v0.8 + - name: Install Brew dependencies + run: | + brew bundle - name: Docker meta id: meta @@ -35,9 +53,12 @@ jobs: - name: Build and push id: build run: | - go run ./cmd/containerbuild --docker-repo ghcr.io/techarohq/anubis --slog-level debug + npm ci + npm run container env: PULL_REQUEST_ID: ${{ github.event.number }} + DOCKER_REPO: ghcr.io/techarohq/anubis + SLOG_LEVEL: debug - run: | echo "Test this with:" diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index bfb095c..c3a532f 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -26,11 +26,29 @@ jobs: fetch-tags: true fetch-depth: 0 - - uses: actions/setup-go@v5 + - name: Set up Homebrew + uses: Homebrew/actions/setup-homebrew@master + + - name: Setup Homebrew cellar cache + uses: actions/cache@v4 with: - go-version: '1.24.x' + 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- - - uses: ko-build/setup-ko@v0.8 + - name: Install Brew dependencies + run: | + brew bundle - name: Log into registry uses: docker/login-action@v3 @@ -48,11 +66,14 @@ jobs: - name: Build and push id: build run: | - go run ./cmd/containerbuild --docker-repo ghcr.io/techarohq/anubis --slog-level debug + npm ci + npm run container + env: + DOCKER_REPO: ghcr.io/techarohq/anubis + SLOG_LEVEL: debug - name: Generate artifact attestation uses: actions/attest-build-provenance@v2 - if: ${{github.event_name == 'pull_request'}} with: subject-name: ghcr.io/techarohq/anubis subject-digest: ${{ steps.build.outputs.digest }} diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index d112342..2837c98 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -69,8 +69,13 @@ jobs: npx --yes playwright@1.50.1 install --with-deps npx --yes playwright@1.50.1 run-server --port 3000 & + - name: install node deps + run: | + npm ci + npm run assets + - name: Build run: go build ./... - name: Test - run: go test -v ./... + run: npm run test @@ -5,3 +5,5 @@ # Go binaries and test artifacts main *.test + +node_modules
\ No newline at end of file @@ -1,4 +1,7 @@ # programming languages brew "go@1.24" brew "node" -brew "ko"
\ No newline at end of file +brew "ko" +brew "esbuild" +brew "zstd" +brew "brotli"
\ No newline at end of file diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 8906bd4..0000000 --- a/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -FROM docker.io/library/golang:1.24 AS build -ARG BUILDKIT_SBOM_SCAN_CONTEXT=true BUILDKIT_SBOM_SCAN_STAGE=true - -WORKDIR /app -COPY go.mod go.sum /app/ -RUN go mod download - -COPY . . -RUN --mount=type=cache,target=/root/.cache \ - VERSION=$(git describe --tags --always --dirty) \ - && go build -o /app/bin/anubis -ldflags="-X github.com/TecharoHQ/anubis.Version=${VERSION}" ./cmd/anubis - -FROM docker.io/library/debian:bookworm AS runtime -ARG BUILDKIT_SBOM_SCAN_STAGE=true -RUN apt-get update \ - && apt-get -y install ca-certificates - -COPY --from=build /app/bin/anubis /app/bin/anubis - -HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 CMD ["/app/bin/anubis", "--healthcheck"] -CMD ["/app/bin/anubis"] - -LABEL org.opencontainers.image.source="https://github.com/TecharoHQ/anubis" diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index 78992fa..e0ebdcb 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -1,6 +1,11 @@ -<!-- delete me and describe your change here --> +<!-- +delete me and describe your change here, give enough context for a maintainer to understand what and why + +See https://anubis.techaro.lol/docs/developer/code-quality for more information +--> Checklist: - [ ] Added a description of the changes to the `[Unreleased]` section of docs/docs/CHANGELOG.md -- [ ] Tested this at least manually +- [ ] Added test cases to [the relevant parts of the codebase](https://anubis.techaro.lol/docs/developer/code-quality) +- [ ] Ran integration tests `npm run test:integration` diff --git a/docs/docs/CHANGELOG.md b/docs/docs/CHANGELOG.md index 29f9416..a16b703 100644 --- a/docs/docs/CHANGELOG.md +++ b/docs/docs/CHANGELOG.md @@ -14,6 +14,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Hide the directory listings for Anubis' internal static content - Changed `--debug-x-real-ip-default` to `--use-remote-address`, getting the IP address from the request's socket address instead. - DroneBL lookups have been disabled by default +- Static asset builds are now done on demand instead of the results being committed to source control +- The Dockerfile has been removed as it is no longer in use +- Developer documentation has been added to the docs site ## v1.15.0 diff --git a/docs/docs/developer/_category_.json b/docs/docs/developer/_category_.json new file mode 100644 index 0000000..cf3805e --- /dev/null +++ b/docs/docs/developer/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Developer guides", + "position": 50, + "link": { + "type": "generated-index", + "description": "Guides and suggestions to make Anubis development go smoothly for everyone." + } +}
\ No newline at end of file diff --git a/docs/docs/developer/code-quality.md b/docs/docs/developer/code-quality.md new file mode 100644 index 0000000..6dcc44a --- /dev/null +++ b/docs/docs/developer/code-quality.md @@ -0,0 +1,31 @@ +--- +title: Code quality guidelines +--- + +When submitting code to Anubis, please take the time to consider the fact that this project is security software. If things go bad, bots can pummel sites into oblivion. This is not ideal for uptime. + +As such, code reviews will be a bit more strict than you have seen in other projects. This is not people trying to be mean, this is a side effect of taking the problem seriously. + +When making code changes, try to do the following: + +- If you're submitting a bugfix, add a test case for it +- If you're changing the JavaScript, make sure the integration tests pass (`npm run test:integration`) + +## Commit messages + +Anubis follows the Go project's conventions for commit messages. In general, an ideal commit message should read like this: + +```text +path/to/folder: brief description of the change + +If the change is subtle, has implementation consequences, or is otherwise +not entirely self-describing: take the time to spell out why. If things +are very subtle, please also amend the documentation accordingly +``` + +The subject of a commit message should be the second half of the sentence "This commit changes the Anubis project to:". Here's a few examples: + +- `disable DroneBL by default` +- `port the challenge to WebAssembly` + +The extended commit message is also your place to give rationale for a new feature. When maintainers are reviewing your code, they will use this to figure out if the burden from feature maintainership is worth the merge. diff --git a/docs/docs/developer/local-dev.md b/docs/docs/developer/local-dev.md new file mode 100644 index 0000000..68634a4 --- /dev/null +++ b/docs/docs/developer/local-dev.md @@ -0,0 +1,57 @@ +--- +title: Local development +--- + +:::note + +TL;DR: `npm ci && npm run dev` + +::: + +Anubis requires the following tools to be installed to do local development: + +- [Go](https://go.dev) - the programming language that Anubis is written in +- [esbuild](https://esbuild.github.io/) - the JavaScript bundler Anubis uses for its production JS assets +- [Node.JS & NPM](https://nodejs.org/en) - manages some build dependencies +- `gzip` - compresses production JS (part of coreutils) +- `zstd` - compresses production JS +- `brotli` - compresses production JS + +If you have [Homebrew](https://brew.sh) installed, you can install all the dependencies with one command: + +```text +brew bundle +``` + +If you don't, you may need to figure out equivalents to the packages in Homebrew. + +## Running Anubis locally + +```text +npm run dev +``` + +Or to do it manually: + +- Run `npm run assets` every time you change the CSS/JavaScript +- `go run ./cmd/anubis` with any CLI flags you want + +## Building JS/CSS assets + +```text +npm run assets +``` + +If you change the build process, make sure to update `build.sh` accordingly. + +## Production-ready builds + +```text +npm run container +``` + +This builds a prod-ready container image with [ko](https://ko.build). If you want to change where the container image is pushed, you need to use environment variables: + +```text +DOCKER_REPO=registry.host/org/repo DOCKER_METADATA_OUTPUT_TAGS=registry.host/org/repo:latest npm run container +``` diff --git a/docs/docs/developer/signed-commits.md b/docs/docs/developer/signed-commits.md new file mode 100644 index 0000000..aa96f22 --- /dev/null +++ b/docs/docs/developer/signed-commits.md @@ -0,0 +1,7 @@ +--- +title: Signed commits +--- + +Anubis requires developers to sign their commits. This is done so that we can have a better chain of custody from contribution to owner. For more information about commit signing, [read here](https://www.freecodecamp.org/news/what-is-commit-signing-in-git/). + +We do not require GPG. SSH signed commits are fine. For an overview on how to set up commit signing with your SSH key, [read here](https://dev.to/ccoveille/git-the-complete-guide-to-sign-your-commits-with-an-ssh-key-35bg). diff --git a/xess/package-lock.json b/package-lock.json index 3941c2f..0e60570 100644 --- a/xess/package-lock.json +++ b/package-lock.json @@ -2408,4 +2408,4 @@ } } } -} +}
\ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..aeb2f2a --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ + "name": "@techaro/anubis", + "version": "1.0.0-see-VERSION-file", + "description": "", + "main": "index.js", + "scripts": { + "test": "npm run assets && go test ./...", + "test:integration": "npm run assets && go test ./internal/test", + "assets": "./web/build.sh && ./xess/build.sh", + "dev": "npm run assets && go run ./cmd/anubis", + "container": "npm run assets && go run ./cmd/containerbuild" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "cssnano": "^7.0.6", + "cssnano-preset-advanced": "^7.0.6", + "postcss-cli": "^11.0.0", + "postcss-import": "^16.1.0", + "postcss-import-url": "^7.2.0", + "postcss-url": "^10.1.3" + } +}
\ No newline at end of file diff --git a/web/build.sh b/web/build.sh new file mode 100755 index 0000000..70492d7 --- /dev/null +++ b/web/build.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -euo pipefail + +cd "$(dirname "$0")" + +esbuild js/main.mjs --sourcemap --bundle --minify --outfile=static/js/main.mjs +gzip -f -k static/js/main.mjs +zstd -f -k --ultra -22 static/js/main.mjs +brotli -fZk static/js/main.mjs
\ No newline at end of file diff --git a/web/embed.go b/web/embed.go index 6f5902f..e572e35 100644 --- a/web/embed.go +++ b/web/embed.go @@ -3,10 +3,6 @@ package web import "embed" //go:generate go tool github.com/a-h/templ/cmd/templ generate -//go:generate esbuild js/main.mjs --sourcemap --bundle --minify --outfile=static/js/main.mjs -//go:generate gzip -f -k static/js/main.mjs -//go:generate zstd -f -k --ultra -22 static/js/main.mjs -//go:generate brotli -fZk static/js/main.mjs var ( //go:embed static diff --git a/web/static/js/.gitignore b/web/static/js/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/web/static/js/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore
\ No newline at end of file diff --git a/web/static/js/main.mjs b/web/static/js/main.mjs deleted file mode 100644 index a934289..0000000 --- a/web/static/js/main.mjs +++ /dev/null @@ -1,2 +0,0 @@ -(()=>{function p(r,n=5,t=navigator.hardwareConcurrency||1){return console.debug("fast algo"),new Promise((e,o)=>{let s=URL.createObjectURL(new Blob(["(",y(),")()"],{type:"application/javascript"})),a=[];for(let i=0;i<t;i++){let c=new Worker(s);c.onmessage=d=>{a.forEach(u=>u.terminate()),c.terminate(),e(d.data)},c.onerror=d=>{c.terminate(),o()},c.postMessage({data:r,difficulty:n,nonce:i,threads:t}),a.push(c)}URL.revokeObjectURL(s)})}function y(){return function(){let r=t=>{let e=new TextEncoder().encode(t);return crypto.subtle.digest("SHA-256",e.buffer)};function n(t){return Array.from(t).map(e=>e.toString(16).padStart(2,"0")).join("")}addEventListener("message",async t=>{let e=t.data.data,o=t.data.difficulty,s,a=t.data.nonce,i=t.data.threads;for(;;){let c=await r(e+a),d=new Uint8Array(c),u=!0;for(let m=0;m<o;m++){let l=Math.floor(m/2),g=m%2;if((d[l]>>(g===0?4:0)&15)!==0){u=!1;break}}if(u){s=n(d),console.log(s);break}a+=i}postMessage({hash:s,data:e,difficulty:o,nonce:a})})}.toString()}function f(r,n=5,t=1){return console.debug("slow algo"),new Promise((e,o)=>{let s=URL.createObjectURL(new Blob(["(",b(),")()"],{type:"application/javascript"})),a=new Worker(s);a.onmessage=i=>{a.terminate(),e(i.data)},a.onerror=i=>{a.terminate(),o()},a.postMessage({data:r,difficulty:n}),URL.revokeObjectURL(s)})}function b(){return function(){let r=n=>{let t=new TextEncoder().encode(n);return crypto.subtle.digest("SHA-256",t.buffer).then(e=>Array.from(new Uint8Array(e)).map(o=>o.toString(16).padStart(2,"0")).join(""))};addEventListener("message",async n=>{let t=n.data.data,e=n.data.difficulty,o,s=0;do o=await r(t+s++);while(o.substring(0,e)!==Array(e+1).join("0"));s-=1,postMessage({hash:o,data:t,difficulty:e,nonce:s})})}.toString()}var L={fast:p,slow:f},w=(r="",n={})=>{let t=new URL(r,window.location.href);return Object.entries(n).forEach(e=>{let[o,s]=e;t.searchParams.set(o,s)}),t.toString()},h=(r,n)=>w(`/.within.website/x/cmd/anubis/static/img/${r}.webp`,{cacheBuster:n});(async()=>{let r=document.getElementById("status"),n=document.getElementById("image"),t=document.getElementById("title"),e=document.getElementById("spinner"),o=JSON.parse(document.getElementById("anubis_version").textContent);r.innerHTML="Calculating...";let{challenge:s,rules:a}=await fetch("/.within.website/x/cmd/anubis/api/make-challenge",{method:"POST"}).then(l=>{if(!l.ok)throw new Error("Failed to fetch config");return l.json()}).catch(l=>{throw t.innerHTML="Oh no!",r.innerHTML=`Failed to fetch config: ${l.message}`,n.src=h("sad",o),e.innerHTML="",e.style.display="none",l}),i=L[a.algorithm];if(!i){t.innerHTML="Oh no!",r.innerHTML="Failed to resolve check algorithm. You may want to reload the page.",n.src=h("sad",o),e.innerHTML="",e.style.display="none";return}r.innerHTML=`Calculating...<br/>Difficulty: ${a.report_as}`;let c=Date.now(),{hash:d,nonce:u}=await i(s,a.difficulty),m=Date.now();console.log({hash:d,nonce:u}),t.innerHTML="Success!",r.innerHTML=`Done! Took ${m-c}ms, ${u} iterations`,n.src=h("happy",o),e.innerHTML="",e.style.display="none",setTimeout(()=>{let l=window.location.href;window.location.href=w("/.within.website/x/cmd/anubis/api/pass-challenge",{response:d,nonce:u,redir:l,elapsedTime:m-c})},250)})();})(); -//# sourceMappingURL=main.mjs.map diff --git a/web/static/js/main.mjs.br b/web/static/js/main.mjs.br Binary files differdeleted file mode 100644 index 6bfd987..0000000 --- a/web/static/js/main.mjs.br +++ /dev/null diff --git a/web/static/js/main.mjs.gz b/web/static/js/main.mjs.gz Binary files differdeleted file mode 100644 index c88b342..0000000 --- a/web/static/js/main.mjs.gz +++ /dev/null diff --git a/web/static/js/main.mjs.map b/web/static/js/main.mjs.map deleted file mode 100644 index 7cad28b..0000000 --- a/web/static/js/main.mjs.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "sources": ["../../js/proof-of-work.mjs", "../../js/proof-of-work-slow.mjs", "../../js/main.mjs"], - "sourcesContent": ["export default function process(data, difficulty = 5, threads = (navigator.hardwareConcurrency || 1)) {\n console.debug(\"fast algo\");\n return new Promise((resolve, reject) => {\n let webWorkerURL = URL.createObjectURL(new Blob([\n '(', processTask(), ')()'\n ], { type: 'application/javascript' }));\n\n const workers = [];\n\n for (let i = 0; i < threads; i++) {\n let worker = new Worker(webWorkerURL);\n\n worker.onmessage = (event) => {\n workers.forEach(worker => worker.terminate());\n worker.terminate();\n resolve(event.data);\n };\n\n worker.onerror = (event) => {\n worker.terminate();\n reject();\n };\n\n worker.postMessage({\n data,\n difficulty,\n nonce: i,\n threads,\n });\n\n workers.push(worker);\n }\n\n URL.revokeObjectURL(webWorkerURL);\n });\n}\n\nfunction processTask() {\n return function () {\n const sha256 = (text) => {\n const encoded = new TextEncoder().encode(text);\n return crypto.subtle.digest(\"SHA-256\", encoded.buffer);\n };\n\n function uint8ArrayToHexString(arr) {\n return Array.from(arr)\n .map((c) => c.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n\n addEventListener('message', async (event) => {\n let data = event.data.data;\n let difficulty = event.data.difficulty;\n let hash;\n let nonce = event.data.nonce;\n let threads = event.data.threads;\n\n while (true) {\n const currentHash = await sha256(data + nonce);\n const thisHash = new Uint8Array(currentHash);\n let valid = true;\n\n for (let j = 0; j < difficulty; j++) {\n const byteIndex = Math.floor(j / 2); // which byte we are looking at\n const nibbleIndex = j % 2; // which nibble in the byte we are looking at (0 is high, 1 is low)\n\n let nibble = (thisHash[byteIndex] >> (nibbleIndex === 0 ? 4 : 0)) & 0x0F; // Get the nibble\n\n if (nibble !== 0) {\n valid = false;\n break;\n }\n }\n\n if (valid) {\n hash = uint8ArrayToHexString(thisHash);\n console.log(hash);\n break;\n }\n\n nonce += threads;\n }\n\n postMessage({\n hash,\n data,\n difficulty,\n nonce,\n });\n });\n }.toString();\n}\n\n", "// https://dev.to/ratmd/simple-proof-of-work-in-javascript-3kgm\n\nexport default function process(data, difficulty = 5, _threads = 1) {\n console.debug(\"slow algo\");\n return new Promise((resolve, reject) => {\n let webWorkerURL = URL.createObjectURL(new Blob([\n '(', processTask(), ')()'\n ], { type: 'application/javascript' }));\n\n let worker = new Worker(webWorkerURL);\n\n worker.onmessage = (event) => {\n worker.terminate();\n resolve(event.data);\n };\n\n worker.onerror = (event) => {\n worker.terminate();\n reject();\n };\n\n worker.postMessage({\n data,\n difficulty\n });\n\n URL.revokeObjectURL(webWorkerURL);\n });\n}\n\nfunction processTask() {\n return function () {\n const sha256 = (text) => {\n const encoded = new TextEncoder().encode(text);\n return crypto.subtle.digest(\"SHA-256\", encoded.buffer)\n .then((result) =>\n Array.from(new Uint8Array(result))\n .map((c) => c.toString(16).padStart(2, \"0\"))\n .join(\"\"),\n );\n };\n\n addEventListener('message', async (event) => {\n let data = event.data.data;\n let difficulty = event.data.difficulty;\n\n let hash;\n let nonce = 0;\n do {\n hash = await sha256(data + nonce++);\n } while (hash.substring(0, difficulty) !== Array(difficulty + 1).join('0'));\n\n nonce -= 1; // last nonce was post-incremented\n\n postMessage({\n hash,\n data,\n difficulty,\n nonce,\n });\n });\n }.toString();\n}", "import processFast from \"./proof-of-work.mjs\";\nimport processSlow from \"./proof-of-work-slow.mjs\";\nimport { testVideo } from \"./video.mjs\";\n\nconst algorithms = {\n \"fast\": processFast,\n \"slow\": processSlow,\n}\n\n// from Xeact\nconst u = (url = \"\", params = {}) => {\n let result = new URL(url, window.location.href);\n Object.entries(params).forEach((kv) => {\n let [k, v] = kv;\n result.searchParams.set(k, v);\n });\n return result.toString();\n};\n\nconst imageURL = (mood, cacheBuster) =>\n u(`/.within.website/x/cmd/anubis/static/img/${mood}.webp`, { cacheBuster });\n\n(async () => {\n const status = document.getElementById('status');\n const image = document.getElementById('image');\n const title = document.getElementById('title');\n const spinner = document.getElementById('spinner');\n const anubisVersion = JSON.parse(document.getElementById('anubis_version').textContent);\n\n // const testarea = document.getElementById('testarea');\n\n // const videoWorks = await testVideo(testarea);\n // console.log(`videoWorks: ${videoWorks}`);\n\n // if (!videoWorks) {\n // title.innerHTML = \"Oh no!\";\n // status.innerHTML = \"Checks failed. Please check your browser's settings and try again.\";\n // image.src = imageURL(\"sad\");\n // spinner.innerHTML = \"\";\n // spinner.style.display = \"none\";\n // return;\n // }\n\n status.innerHTML = 'Calculating...';\n\n const { challenge, rules } = await fetch(\"/.within.website/x/cmd/anubis/api/make-challenge\", { method: \"POST\" })\n .then(r => {\n if (!r.ok) {\n throw new Error(\"Failed to fetch config\");\n }\n return r.json();\n })\n .catch(err => {\n title.innerHTML = \"Oh no!\";\n status.innerHTML = `Failed to fetch config: ${err.message}`;\n image.src = imageURL(\"sad\", anubisVersion);\n spinner.innerHTML = \"\";\n spinner.style.display = \"none\";\n throw err;\n });\n\n const process = algorithms[rules.algorithm];\n if (!process) {\n title.innerHTML = \"Oh no!\";\n status.innerHTML = `Failed to resolve check algorithm. You may want to reload the page.`;\n image.src = imageURL(\"sad\", anubisVersion);\n spinner.innerHTML = \"\";\n spinner.style.display = \"none\";\n return;\n }\n\n status.innerHTML = `Calculating...<br/>Difficulty: ${rules.report_as}`;\n\n const t0 = Date.now();\n const { hash, nonce } = await process(challenge, rules.difficulty);\n const t1 = Date.now();\n console.log({ hash, nonce });\n\n title.innerHTML = \"Success!\";\n status.innerHTML = `Done! Took ${t1 - t0}ms, ${nonce} iterations`;\n image.src = imageURL(\"happy\", anubisVersion);\n spinner.innerHTML = \"\";\n spinner.style.display = \"none\";\n\n setTimeout(() => {\n const redir = window.location.href;\n window.location.href = u(\"/.within.website/x/cmd/anubis/api/pass-challenge\", { response: hash, nonce, redir, elapsedTime: t1 - t0 });\n }, 250);\n})();"], - "mappings": "MAAe,SAARA,EAAyBC,EAAMC,EAAa,EAAGC,EAAW,UAAU,qBAAuB,EAAI,CACpG,eAAQ,MAAM,WAAW,EAClB,IAAI,QAAQ,CAACC,EAASC,IAAW,CACtC,IAAIC,EAAe,IAAI,gBAAgB,IAAI,KAAK,CAC9C,IAAKC,EAAY,EAAG,KACtB,EAAG,CAAE,KAAM,wBAAyB,CAAC,CAAC,EAEhCC,EAAU,CAAC,EAEjB,QAAS,EAAI,EAAG,EAAIL,EAAS,IAAK,CAChC,IAAIM,EAAS,IAAI,OAAOH,CAAY,EAEpCG,EAAO,UAAaC,GAAU,CAC5BF,EAAQ,QAAQC,GAAUA,EAAO,UAAU,CAAC,EAC5CA,EAAO,UAAU,EACjBL,EAAQM,EAAM,IAAI,CACpB,EAEAD,EAAO,QAAWC,GAAU,CAC1BD,EAAO,UAAU,EACjBJ,EAAO,CACT,EAEAI,EAAO,YAAY,CACjB,KAAAR,EACA,WAAAC,EACA,MAAO,EACP,QAAAC,CACF,CAAC,EAEDK,EAAQ,KAAKC,CAAM,CACrB,CAEA,IAAI,gBAAgBH,CAAY,CAClC,CAAC,CACH,CAEA,SAASC,GAAc,CACrB,OAAO,UAAY,CACjB,IAAMI,EAAUC,GAAS,CACvB,IAAMC,EAAU,IAAI,YAAY,EAAE,OAAOD,CAAI,EAC7C,OAAO,OAAO,OAAO,OAAO,UAAWC,EAAQ,MAAM,CACvD,EAEA,SAASC,EAAsBC,EAAK,CAClC,OAAO,MAAM,KAAKA,CAAG,EAClB,IAAKC,GAAMA,EAAE,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,CAAC,EAC1C,KAAK,EAAE,CACZ,CAEA,iBAAiB,UAAW,MAAON,GAAU,CAC3C,IAAIT,EAAOS,EAAM,KAAK,KAClBR,EAAaQ,EAAM,KAAK,WACxBO,EACAC,EAAQR,EAAM,KAAK,MACnBP,EAAUO,EAAM,KAAK,QAEzB,OAAa,CACX,IAAMS,EAAc,MAAMR,EAAOV,EAAOiB,CAAK,EACvCE,EAAW,IAAI,WAAWD,CAAW,EACvCE,EAAQ,GAEZ,QAASC,EAAI,EAAGA,EAAIpB,EAAYoB,IAAK,CACnC,IAAMC,EAAY,KAAK,MAAMD,EAAI,CAAC,EAC5BE,EAAcF,EAAI,EAIxB,IAFcF,EAASG,CAAS,IAAMC,IAAgB,EAAI,EAAI,GAAM,MAErD,EAAG,CAChBH,EAAQ,GACR,KACF,CACF,CAEA,GAAIA,EAAO,CACTJ,EAAOH,EAAsBM,CAAQ,EACrC,QAAQ,IAAIH,CAAI,EAChB,KACF,CAEAC,GAASf,CACX,CAEA,YAAY,CACV,KAAAc,EACA,KAAAhB,EACA,WAAAC,EACA,MAAAgB,CACF,CAAC,CACH,CAAC,CACH,EAAE,SAAS,CACb,CCzFe,SAARO,EAAyBC,EAAMC,EAAa,EAAGC,EAAW,EAAG,CAClE,eAAQ,MAAM,WAAW,EAClB,IAAI,QAAQ,CAACC,EAASC,IAAW,CACtC,IAAIC,EAAe,IAAI,gBAAgB,IAAI,KAAK,CAC9C,IAAKC,EAAY,EAAG,KACtB,EAAG,CAAE,KAAM,wBAAyB,CAAC,CAAC,EAElCC,EAAS,IAAI,OAAOF,CAAY,EAEpCE,EAAO,UAAaC,GAAU,CAC5BD,EAAO,UAAU,EACjBJ,EAAQK,EAAM,IAAI,CACpB,EAEAD,EAAO,QAAWC,GAAU,CAC1BD,EAAO,UAAU,EACjBH,EAAO,CACT,EAEAG,EAAO,YAAY,CACjB,KAAAP,EACA,WAAAC,CACF,CAAC,EAED,IAAI,gBAAgBI,CAAY,CAClC,CAAC,CACH,CAEA,SAASC,GAAc,CACrB,OAAO,UAAY,CACjB,IAAMG,EAAUC,GAAS,CACvB,IAAMC,EAAU,IAAI,YAAY,EAAE,OAAOD,CAAI,EAC7C,OAAO,OAAO,OAAO,OAAO,UAAWC,EAAQ,MAAM,EAClD,KAAMC,GACL,MAAM,KAAK,IAAI,WAAWA,CAAM,CAAC,EAC9B,IAAKC,GAAMA,EAAE,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,CAAC,EAC1C,KAAK,EAAE,CACZ,CACJ,EAEA,iBAAiB,UAAW,MAAOL,GAAU,CAC3C,IAAIR,EAAOQ,EAAM,KAAK,KAClBP,EAAaO,EAAM,KAAK,WAExBM,EACAC,EAAQ,EACZ,GACED,EAAO,MAAML,EAAOT,EAAOe,GAAO,QAC3BD,EAAK,UAAU,EAAGb,CAAU,IAAM,MAAMA,EAAa,CAAC,EAAE,KAAK,GAAG,GAEzEc,GAAS,EAET,YAAY,CACV,KAAAD,EACA,KAAAd,EACA,WAAAC,EACA,MAAAc,CACF,CAAC,CACH,CAAC,CACH,EAAE,SAAS,CACb,CC1DA,IAAMC,EAAa,CACjB,KAAQC,EACR,KAAQA,CACV,EAGMC,EAAI,CAACC,EAAM,GAAIC,EAAS,CAAC,IAAM,CACnC,IAAIC,EAAS,IAAI,IAAIF,EAAK,OAAO,SAAS,IAAI,EAC9C,cAAO,QAAQC,CAAM,EAAE,QAASE,GAAO,CACrC,GAAI,CAACC,EAAGC,CAAC,EAAIF,EACbD,EAAO,aAAa,IAAIE,EAAGC,CAAC,CAC9B,CAAC,EACMH,EAAO,SAAS,CACzB,EAEMI,EAAW,CAACC,EAAMC,IACtBT,EAAE,4CAA4CQ,CAAI,QAAS,CAAE,YAAAC,CAAY,CAAC,GAE3E,SAAY,CACX,IAAMC,EAAS,SAAS,eAAe,QAAQ,EACzCC,EAAQ,SAAS,eAAe,OAAO,EACvCC,EAAQ,SAAS,eAAe,OAAO,EACvCC,EAAU,SAAS,eAAe,SAAS,EAC3CC,EAAgB,KAAK,MAAM,SAAS,eAAe,gBAAgB,EAAE,WAAW,EAgBtFJ,EAAO,UAAY,iBAEnB,GAAM,CAAE,UAAAK,EAAW,MAAAC,CAAM,EAAI,MAAM,MAAM,mDAAoD,CAAE,OAAQ,MAAO,CAAC,EAC5G,KAAKC,GAAK,CACT,GAAI,CAACA,EAAE,GACL,MAAM,IAAI,MAAM,wBAAwB,EAE1C,OAAOA,EAAE,KAAK,CAChB,CAAC,EACA,MAAMC,GAAO,CACZ,MAAAN,EAAM,UAAY,SAClBF,EAAO,UAAY,2BAA2BQ,EAAI,OAAO,GACzDP,EAAM,IAAMJ,EAAS,MAAOO,CAAa,EACzCD,EAAQ,UAAY,GACpBA,EAAQ,MAAM,QAAU,OAClBK,CACR,CAAC,EAEGnB,EAAUD,EAAWkB,EAAM,SAAS,EAC1C,GAAI,CAACjB,EAAS,CACZa,EAAM,UAAY,SAClBF,EAAO,UAAY,sEACnBC,EAAM,IAAMJ,EAAS,MAAOO,CAAa,EACzCD,EAAQ,UAAY,GACpBA,EAAQ,MAAM,QAAU,OACxB,MACF,CAEAH,EAAO,UAAY,kCAAkCM,EAAM,SAAS,GAEpE,IAAMG,EAAK,KAAK,IAAI,EACd,CAAE,KAAAC,EAAM,MAAAC,CAAM,EAAI,MAAMtB,EAAQgB,EAAWC,EAAM,UAAU,EAC3DM,EAAK,KAAK,IAAI,EACpB,QAAQ,IAAI,CAAE,KAAAF,EAAM,MAAAC,CAAM,CAAC,EAE3BT,EAAM,UAAY,WAClBF,EAAO,UAAY,cAAcY,EAAKH,CAAE,OAAOE,CAAK,cACpDV,EAAM,IAAMJ,EAAS,QAASO,CAAa,EAC3CD,EAAQ,UAAY,GACpBA,EAAQ,MAAM,QAAU,OAExB,WAAW,IAAM,CACf,IAAMU,EAAQ,OAAO,SAAS,KAC9B,OAAO,SAAS,KAAOvB,EAAE,mDAAoD,CAAE,SAAUoB,EAAM,MAAAC,EAAO,MAAAE,EAAO,YAAaD,EAAKH,CAAG,CAAC,CACrI,EAAG,GAAG,CACR,GAAG", - "names": ["process", "data", "difficulty", "threads", "resolve", "reject", "webWorkerURL", "processTask", "workers", "worker", "event", "sha256", "text", "encoded", "uint8ArrayToHexString", "arr", "c", "hash", "nonce", "currentHash", "thisHash", "valid", "j", "byteIndex", "nibbleIndex", "process", "data", "difficulty", "_threads", "resolve", "reject", "webWorkerURL", "processTask", "worker", "event", "sha256", "text", "encoded", "result", "c", "hash", "nonce", "algorithms", "process", "u", "url", "params", "result", "kv", "k", "v", "imageURL", "mood", "cacheBuster", "status", "image", "title", "spinner", "anubisVersion", "challenge", "rules", "r", "err", "t0", "hash", "nonce", "t1", "redir"] -} diff --git a/web/static/js/main.mjs.zst b/web/static/js/main.mjs.zst Binary files differdeleted file mode 100644 index 4ed5ca7..0000000 --- a/web/static/js/main.mjs.zst +++ /dev/null diff --git a/xess/.gitignore b/xess/.gitignore index 3c3629e..f44fcaf 100644 --- a/xess/.gitignore +++ b/xess/.gitignore @@ -1 +1 @@ -node_modules +xess.min.css diff --git a/xess/build.sh b/xess/build.sh new file mode 100755 index 0000000..72eec6e --- /dev/null +++ b/xess/build.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +set -euo pipefail + +cd "$(dirname "$0")" +postcss ./xess.css -o xess.min.css
\ No newline at end of file diff --git a/xess/package.json b/xess/package.json deleted file mode 100644 index 2844ca5..0000000 --- a/xess/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "@xeserv/xess", - "version": "1.0.0", - "description": "Xe's CSS", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "build": "postcss xess.css -o xess.min.css" - }, - "author": "", - "license": "ISC", - "devDependencies": { - "cssnano": "^7.0.6", - "cssnano-preset-advanced": "^7.0.6", - "postcss-cli": "^11.0.0", - "postcss-import": "^16.1.0", - "postcss-import-url": "^7.2.0", - "postcss-url": "^10.1.3" - } -}
\ No newline at end of file diff --git a/xess/xess.go b/xess/xess.go index 301767b..18d995d 100644 --- a/xess/xess.go +++ b/xess/xess.go @@ -13,11 +13,10 @@ import ( ) //go:generate go run github.com/a-h/templ/cmd/templ@latest generate -//go:generate npm ci //go:generate npm run build var ( - //go:embed xess.min.css xess.css static + //go:embed *.css static Static embed.FS URL = "/.within.website/x/xess/xess.css" diff --git a/xess/xess.min.css b/xess/xess.min.css deleted file mode 100644 index fc76513..0000000 --- a/xess/xess.min.css +++ /dev/null @@ -1 +0,0 @@ -@font-face{font-display:swap;font-family:Geist;font-style:normal;font-weight:100 900;src:url("data:font/woff2;base64,d09GMgABAAAAAPq4ABUAAAACTIQAAPo7AAFmqAAAAAAAAAAAAAAAAAAAAAAAAAAAGokqG4HrchyaSj9IVkFSkl8/TVZBUjwGYD9TVEFUgTgAj24vfhEICoK8RIH/TjCDryYBNgIkA5lkC4x0AAQgP21ldGEvBZJTB7lBDAdbKCaSA5Yy1t4+YQ8MFdDO0bbCqV4UfVgnxDnsQNSb2zlaAXB9s09QMd0cvEB34M6FqcpW/v/////XJJMY00uAS5KHBxDEYp1W27bbQMUM5tIjhDkMnlYCvWc6HAMjEl6JiL6PYjZOMU/0OgaShZgEwYUnE06xzoJEDnrpVY4yiCAyQswjgsRmpoxnU4NKEKS2m0mS1C5vmGbPXT86cZ2rSFOjvfebSqp7sz95x7KJCHGLRuMCFmH6rQHlXZh+tHfJavDAQ3xgmuATghHYnWEihbs0DO5ijDJmwWBp+nEt4rlxGa6vHhXb9knx+sISg59DfE6pmZlKqtQudTTyhCOUFaEn4ZJfFN9ic2/+c298W8f6OIvfxnXUqVsL1P4+a9WyeyfXdnA65g/8nEspZRE1VVLtqRqbfishDT2Ki2cE4iHin+ilmTCRXlbvU2QR1lJGUp47O/ZYNepzZ36bvKhRJwmKVVLyTljbu/6pHuzef3Vf0V/eZHZn0AeVg2pkezdRW7poe+deAuK49UBKtGWfK54Y48vTx/9S/1f3PiMTycSSk7oFRPj5AADCc0RzNrN7d0nuLpdcjBBCkKQQrIgXqp6Kp4rW |
