widget(0.1.36): better widget ui

This commit is contained in:
tiago
2026-02-28 12:11:07 +00:00
parent a17cd63ade
commit aa73ca2865
32 changed files with 1375 additions and 1344 deletions
+5 -1
View File
@@ -14,4 +14,8 @@ run `bun install` in each Bun package you want to work on to install dependencie
- we recommend [Biome](https://biomejs.dev/) for formatting and linting. please fix all errors and warnings before submitting a PR
- [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) are preferred
- [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) are preferred
## current roadmap
javascript challenges and reputation-based difficulties are the main new feature focus.
+28
View File
@@ -1,11 +1,13 @@
{
"lockfileVersion": 1,
"configVersion": 0,
"workspaces": {
"": {
"name": "cap-demo",
"dependencies": {
"@cap.js/server": "^1.0.13",
"elysia": "^1.3.4",
"lightningcss": "^1.31.1",
},
},
},
@@ -24,6 +26,8 @@
"debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
"elysia": ["elysia@1.3.4", "", { "dependencies": { "cookie": "^1.0.2", "exact-mirror": "0.1.2", "fast-decode-uri-component": "^1.0.1" }, "optionalDependencies": { "@sinclair/typebox": "^0.34.33", "openapi-types": "^12.1.3" }, "peerDependencies": { "file-type": ">= 20.0.0", "typescript": ">= 5.0.0" } }, "sha512-kAfM3Zwovy3z255IZgTKVxBw91HbgKhYl3TqrGRdZqqr+Fd+4eKOfvxgaKij22+MZLczPzIHtscAmvfpI3+q/A=="],
"exact-mirror": ["exact-mirror@0.1.2", "", { "peerDependencies": { "@sinclair/typebox": "^0.34.15" }, "optionalPeers": ["@sinclair/typebox"] }, "sha512-wFCPCDLmHbKGUb8TOi/IS7jLsgR8WVDGtDK3CzcB4Guf/weq7G+I+DkXiRSZfbemBFOxOINKpraM6ml78vo8Zw=="],
@@ -36,6 +40,30 @@
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
"lightningcss": ["lightningcss@1.31.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.31.1", "lightningcss-darwin-arm64": "1.31.1", "lightningcss-darwin-x64": "1.31.1", "lightningcss-freebsd-x64": "1.31.1", "lightningcss-linux-arm-gnueabihf": "1.31.1", "lightningcss-linux-arm64-gnu": "1.31.1", "lightningcss-linux-arm64-musl": "1.31.1", "lightningcss-linux-x64-gnu": "1.31.1", "lightningcss-linux-x64-musl": "1.31.1", "lightningcss-win32-arm64-msvc": "1.31.1", "lightningcss-win32-x64-msvc": "1.31.1" } }, "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ=="],
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.31.1", "", { "os": "android", "cpu": "arm64" }, "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg=="],
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.31.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg=="],
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.31.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA=="],
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.31.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A=="],
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.31.1", "", { "os": "linux", "cpu": "arm" }, "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g=="],
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.31.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg=="],
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.31.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg=="],
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.31.1", "", { "os": "linux", "cpu": "x64" }, "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA=="],
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.31.1", "", { "os": "linux", "cpu": "x64" }, "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA=="],
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.31.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w=="],
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.31.1", "", { "os": "win32", "cpu": "x64" }, "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw=="],
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="],
+24 -2
View File
@@ -1,7 +1,23 @@
import fs from "node:fs/promises";
import { Elysia, file } from "elysia";
import { transform } from "lightningcss";
import Cap from "../../server/index.js";
const processCSS = async () => {
const raw = await fs.readFile("../../widget/src/src/cap.css", "utf-8");
const { code } = transform({
filename: "cap.css",
code: Buffer.from(raw),
minify: true,
targets: {
chrome: 90 << 16,
firefox: 90 << 16,
safari: 14 << 16,
},
});
return code.toString();
};
const cap = new Cap({
tokens_store_path: ".data/tokensList.json",
});
@@ -11,14 +27,15 @@ const app = new Elysia();
app.get("/", () => file("./index.html"));
app.get("/cap.js", async ({ set }) => {
// in the newest version, the worker is injected into the main file
// in the newest version, the worker and CSS are injected into the main file
// by a build script. since we don't have a build script here,
// we'll need to run a minimal build ourselves.
const main = await fs.readFile("../../widget/src/src/cap.js", "utf-8");
const worker = await fs.readFile("../../widget/src/src/worker.js", "utf-8");
const css = await processCSS();
const bundle = main.replace("%%workerScript%%", worker);
const bundle = main.replace("%%workerScript%%", worker).replace("%%capCSS%%", css);
set.headers = {
"Content-Type": "application/javascript",
@@ -29,6 +46,11 @@ app.get("/cap.js", async ({ set }) => {
app.get("/cap-floating.js", () => file("../../widget/src/src/cap-floating.js"));
app.get("/cap.css", async ({ set }) => {
set.headers = { "Content-Type": "text/css" };
return processCSS();
});
app.post("/api/challenge", () => cap.createChallenge());
app.post("/api/redeem", async ({ body, set }) => {
+2 -1
View File
@@ -12,6 +12,7 @@
},
"dependencies": {
"@cap.js/server": "^1.0.13",
"elysia": "^1.3.4"
"elysia": "^1.3.4",
"lightningcss": "^1.31.1"
}
}
-54
View File
@@ -1,54 +0,0 @@
{
"lockfileVersion": 1,
"workspaces": {
"": {
"dependencies": {
"@cap.js/server": "latest",
"elysia": "^1.3.3",
},
},
},
"packages": {
"@cap.js/server": ["@cap.js/server@1.0.15", "", { "dependencies": { "@types/node": "^22.14.1", "typescript": "^5.8.3" } }, "sha512-mcDbHAL4ar5O4gnDE+62ZPeXhLXxd1KKHzJCsZfn81HY8Fgo5ousxYCnzhsLfki5sH6sO6jpNtS4MZXlKDq+fA=="],
"@sinclair/typebox": ["@sinclair/typebox@0.34.33", "", {}, "sha512-5HAV9exOMcXRUxo+9iYB5n09XxzCXnfy4VTNW4xnDv+FgjzAGY989C28BIdljKqmF+ZltUwujE3aossvcVtq6g=="],
"@tokenizer/inflate": ["@tokenizer/inflate@0.2.7", "", { "dependencies": { "debug": "^4.4.0", "fflate": "^0.8.2", "token-types": "^6.0.0" } }, "sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg=="],
"@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
"@types/node": ["@types/node@22.15.29", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-LNdjOkUDlU1RZb8e1kOIUpN1qQUlzGkEtbVNo53vbrwDg5om6oduhm4SiUaPW5ASTXhAiP0jInWG8Qx9fVlOeQ=="],
"cookie": ["cookie@1.0.2", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="],
"debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
"elysia": ["elysia@1.3.3", "", { "dependencies": { "cookie": "^1.0.2", "exact-mirror": "0.1.2", "fast-decode-uri-component": "^1.0.1" }, "optionalDependencies": { "@sinclair/typebox": "^0.34.33", "openapi-types": "^12.1.3" }, "peerDependencies": { "file-type": ">= 20.0.0", "typescript": ">= 5.0.0" } }, "sha512-x6a89d4h0xX9TB0CSGkUuKNqIK776HBJw0WHtK1B3ViQqZijsLnOor6be/7TwVl8MG6m59NHGHbmbBS6lnCXSw=="],
"exact-mirror": ["exact-mirror@0.1.2", "", { "peerDependencies": { "@sinclair/typebox": "^0.34.15" }, "optionalPeers": ["@sinclair/typebox"] }, "sha512-wFCPCDLmHbKGUb8TOi/IS7jLsgR8WVDGtDK3CzcB4Guf/weq7G+I+DkXiRSZfbemBFOxOINKpraM6ml78vo8Zw=="],
"fast-decode-uri-component": ["fast-decode-uri-component@1.0.1", "", {}, "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg=="],
"fflate": ["fflate@0.8.2", "", {}, "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A=="],
"file-type": ["file-type@21.0.0", "", { "dependencies": { "@tokenizer/inflate": "^0.2.7", "strtok3": "^10.2.2", "token-types": "^6.0.0", "uint8array-extras": "^1.4.0" } }, "sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg=="],
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="],
"peek-readable": ["peek-readable@7.0.0", "", {}, "sha512-nri2TO5JE3/mRryik9LlHFT53cgHfRK0Lt0BAZQXku/AW3E6XLt2GaY8siWi7dvW/m1z0ecn+J+bpDa9ZN3IsQ=="],
"strtok3": ["strtok3@10.2.2", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "peek-readable": "^7.0.0" } }, "sha512-Xt18+h4s7Z8xyZ0tmBoRmzxcop97R4BAh+dXouUDCYn+Em+1P3qpkUfI5ueWLT8ynC5hZ+q4iPEmGG1urvQGBg=="],
"token-types": ["token-types@6.0.0", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA=="],
"typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
"uint8array-extras": ["uint8array-extras@1.4.0", "", {}, "sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ=="],
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
}
}
-22
View File
@@ -1,22 +0,0 @@
import { Elysia, file } from "elysia";
import { capMiddleware } from "../../../checkpoints/elysia/index";
// import { capMiddleware } from "@cap.js/middleware-elysia";
new Elysia()
.use(
capMiddleware({
/*
token_validity_hours: 32, // how long the token is valid for
tokens_store_path: ".data/tokensList.json",
token_size: 16, // token size in bytes
verification_template_path: join(
dirname(fileURLToPath(import.meta.url)),
"./index.html"
),
scoping: "scoped", // 'global' | 'scoped'
*/
}),
)
.get("/", () => file("success.html"))
.listen(3000);
-6
View File
@@ -1,6 +0,0 @@
{
"dependencies": {
"@cap.js/server": "latest",
"elysia": "^1.3.3"
}
}
-52
View File
@@ -1,52 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Success!</title>
<meta charset="UTF-8" />
<style>
body {
margin: 0px;
padding: 0px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
height: 100vh;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue",
sans-serif;
text-align: center;
}
h1 {
font-size: 4em;
margin-bottom: 0px;
}
p {
max-width: 250px;
line-height: 1.4;
}
button {
background-color: transparent;
font-weight: 500;
border: none;
cursor: pointer;
font-family: inherit;
font-size: 16px;
}
</style>
</head>
<body>
<div class="content">
<h1>🎉</h1>
<p>You have successfully passed Cap's checkpoint.</p>
<button>Try again</button>
</div>
</body>
<script>
document.querySelector("button").addEventListener("click", () => {
document.cookie =
"__cap_clearance=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/";
location.reload();
});
</script>
</html>
-157
View File
@@ -1,157 +0,0 @@
{
"lockfileVersion": 1,
"workspaces": {
"": {
"dependencies": {
"@cap.js/server": "latest",
"cookie-parser": "^1.4.7",
"express": "^5.1.0",
},
},
},
"packages": {
"@cap.js/server": ["@cap.js/server@1.0.15", "", { "dependencies": { "@types/node": "^22.14.1", "typescript": "^5.8.3" } }, "sha512-mcDbHAL4ar5O4gnDE+62ZPeXhLXxd1KKHzJCsZfn81HY8Fgo5ousxYCnzhsLfki5sH6sO6jpNtS4MZXlKDq+fA=="],
"@types/node": ["@types/node@22.15.29", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-LNdjOkUDlU1RZb8e1kOIUpN1qQUlzGkEtbVNo53vbrwDg5om6oduhm4SiUaPW5ASTXhAiP0jInWG8Qx9fVlOeQ=="],
"accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="],
"body-parser": ["body-parser@2.2.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.0", "http-errors": "^2.0.0", "iconv-lite": "^0.6.3", "on-finished": "^2.4.1", "qs": "^6.14.0", "raw-body": "^3.0.0", "type-is": "^2.0.0" } }, "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg=="],
"bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="],
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
"call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="],
"content-disposition": ["content-disposition@1.0.0", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg=="],
"content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="],
"cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="],
"cookie-parser": ["cookie-parser@1.4.7", "", { "dependencies": { "cookie": "0.7.2", "cookie-signature": "1.0.6" } }, "sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw=="],
"cookie-signature": ["cookie-signature@1.0.6", "", {}, "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="],
"debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
"depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
"ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="],
"encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="],
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
"es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
"escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="],
"etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="],
"express": ["express@5.1.0", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.0", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA=="],
"finalhandler": ["finalhandler@2.1.0", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q=="],
"forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="],
"fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="],
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
"get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
"get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
"has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
"http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="],
"iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
"ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="],
"is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="],
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
"media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="],
"merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="],
"mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="],
"mime-types": ["mime-types@3.0.1", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA=="],
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
"object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="],
"on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="],
"once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
"parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="],
"path-to-regexp": ["path-to-regexp@8.2.0", "", {}, "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ=="],
"proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="],
"qs": ["qs@6.14.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w=="],
"range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="],
"raw-body": ["raw-body@3.0.0", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.6.3", "unpipe": "1.0.0" } }, "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g=="],
"router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="],
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
"send": ["send@1.2.0", "", { "dependencies": { "debug": "^4.3.5", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.0", "mime-types": "^3.0.1", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.1" } }, "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw=="],
"serve-static": ["serve-static@2.2.0", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ=="],
"setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="],
"side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="],
"side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="],
"side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="],
"side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="],
"statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="],
"toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
"type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="],
"typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
"unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="],
"vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="],
"wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
"express/cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="],
}
}
-32
View File
@@ -1,32 +0,0 @@
import path, { dirname } from "node:path";
import { fileURLToPath } from "node:url";
import cookieParser from "cookie-parser";
import express from "express";
import { capCheckpoint } from "../../../checkpoints/express/index";
// import { capCheckpoint } from "@cap.js/checkpoint-express";
const app = express();
const __dirname = dirname(fileURLToPath(import.meta.url));
app.use(express.json());
app.use(cookieParser());
app.use(
capCheckpoint({
/*
token_validity_hours: 32,
tokens_store_path: ".data/tokensList.json",
token_size: 16,
verification_template_path: join(__dirname, "./index.html"),
*/
}),
);
app.get("/", (_, res) => {
res.sendFile(path.join(__dirname, "success.html"));
});
app.listen(3000, () => {
console.log(`Server running on http://localhost:3000`);
});
-7
View File
@@ -1,7 +0,0 @@
{
"dependencies": {
"@cap.js/server": "latest",
"cookie-parser": "^1.4.7",
"express": "^5.1.0"
}
}
-52
View File
@@ -1,52 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Success!</title>
<meta charset="UTF-8" />
<style>
body {
margin: 0px;
padding: 0px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
height: 100vh;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue",
sans-serif;
text-align: center;
}
h1 {
font-size: 4em;
margin-bottom: 0px;
}
p {
max-width: 250px;
line-height: 1.4;
}
button {
background-color: transparent;
font-weight: 500;
border: none;
cursor: pointer;
font-family: inherit;
font-size: 16px;
}
</style>
</head>
<body>
<div class="content">
<h1>🎉</h1>
<p>You have successfully passed Cap's checkpoint.</p>
<button>Try again</button>
</div>
</body>
<script>
document.querySelector("button").addEventListener("click", () => {
document.cookie =
"__cap_clearance=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/";
location.reload();
});
</script>
</html>
-22
View File
@@ -1,22 +0,0 @@
{
"lockfileVersion": 1,
"workspaces": {
"": {
"dependencies": {
"@cap.js/server": "latest",
"hono": "^4.7.10",
},
},
},
"packages": {
"@cap.js/server": ["@cap.js/server@1.0.15", "", { "dependencies": { "@types/node": "^22.14.1", "typescript": "^5.8.3" } }, "sha512-mcDbHAL4ar5O4gnDE+62ZPeXhLXxd1KKHzJCsZfn81HY8Fgo5ousxYCnzhsLfki5sH6sO6jpNtS4MZXlKDq+fA=="],
"@types/node": ["@types/node@22.15.28", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-I0okKVDmyKR281I0UIFV7EWAWRnR0gkuSKob5wVcByyyhr7Px/slhkQapcYX4u00ekzNWaS1gznKZnuzxwo4pw=="],
"hono": ["hono@4.7.10", "", {}, "sha512-QkACju9MiN59CKSY5JsGZCYmPZkA6sIW6OFCUp7qDjZu6S6KHtJHhAc9Uy9mV9F8PJ1/HQ3ybZF2yjCa/73fvQ=="],
"typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
}
}
-24
View File
@@ -1,24 +0,0 @@
import { Hono } from "hono";
import { serveStatic } from "hono/bun";
import { capCheckpoint } from "../../../checkpoints/hono/index";
// import { capCheckpoint } from "@cap.js/checkpoint-hono";
const app = new Hono();
app.use(
"*",
capCheckpoint({
/*
token_validity_hours: 32, // how long the token is valid for
tokens_store_path: ".data/tokensList.json",
token_size: 16, // token size in bytes
verification_template_path: join(
dirname(fileURLToPath(import.meta.url)),
"./index.html"
)
*/
})
);
app.get("/", serveStatic({ path: "./success.html" }));
export default app;
-6
View File
@@ -1,6 +0,0 @@
{
"dependencies": {
"@cap.js/server": "latest",
"hono": "^4.7.10"
}
}
-52
View File
@@ -1,52 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Success!</title>
<meta charset="UTF-8" />
<style>
body {
margin: 0px;
padding: 0px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
height: 100vh;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue",
sans-serif;
text-align: center;
}
h1 {
font-size: 4em;
margin-bottom: 0px;
}
p {
max-width: 250px;
line-height: 1.4;
}
button {
background-color: transparent;
font-weight: 500;
border: none;
cursor: pointer;
font-family: inherit;
font-size: 16px;
}
</style>
</head>
<body>
<div class="content">
<h1>🎉</h1>
<p>You have successfully passed Cap's checkpoint.</p>
<button>Try again</button>
</div>
</body>
<script>
document.querySelector("button").addEventListener("click", () => {
document.cookie =
"__cap_clearance=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/";
location.reload();
});
</script>
</html>
+28
View File
@@ -1,11 +1,13 @@
{
"lockfileVersion": 1,
"configVersion": 0,
"workspaces": {
"": {
"name": "cap-demo",
"dependencies": {
"@cap.js/server": "^1.0.13",
"elysia": "^1.3.4",
"lightningcss": "^1.31.1",
},
},
},
@@ -24,6 +26,8 @@
"debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
"elysia": ["elysia@1.3.4", "", { "dependencies": { "cookie": "^1.0.2", "exact-mirror": "0.1.2", "fast-decode-uri-component": "^1.0.1" }, "optionalDependencies": { "@sinclair/typebox": "^0.34.33", "openapi-types": "^12.1.3" }, "peerDependencies": { "file-type": ">= 20.0.0", "typescript": ">= 5.0.0" } }, "sha512-kAfM3Zwovy3z255IZgTKVxBw91HbgKhYl3TqrGRdZqqr+Fd+4eKOfvxgaKij22+MZLczPzIHtscAmvfpI3+q/A=="],
"exact-mirror": ["exact-mirror@0.1.2", "", { "peerDependencies": { "@sinclair/typebox": "^0.34.15" }, "optionalPeers": ["@sinclair/typebox"] }, "sha512-wFCPCDLmHbKGUb8TOi/IS7jLsgR8WVDGtDK3CzcB4Guf/weq7G+I+DkXiRSZfbemBFOxOINKpraM6ml78vo8Zw=="],
@@ -36,6 +40,30 @@
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
"lightningcss": ["lightningcss@1.31.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.31.1", "lightningcss-darwin-arm64": "1.31.1", "lightningcss-darwin-x64": "1.31.1", "lightningcss-freebsd-x64": "1.31.1", "lightningcss-linux-arm-gnueabihf": "1.31.1", "lightningcss-linux-arm64-gnu": "1.31.1", "lightningcss-linux-arm64-musl": "1.31.1", "lightningcss-linux-x64-gnu": "1.31.1", "lightningcss-linux-x64-musl": "1.31.1", "lightningcss-win32-arm64-msvc": "1.31.1", "lightningcss-win32-x64-msvc": "1.31.1" } }, "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ=="],
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.31.1", "", { "os": "android", "cpu": "arm64" }, "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg=="],
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.31.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg=="],
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.31.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA=="],
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.31.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A=="],
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.31.1", "", { "os": "linux", "cpu": "arm" }, "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g=="],
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.31.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg=="],
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.31.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg=="],
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.31.1", "", { "os": "linux", "cpu": "x64" }, "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA=="],
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.31.1", "", { "os": "linux", "cpu": "x64" }, "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA=="],
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.31.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w=="],
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.31.1", "", { "os": "win32", "cpu": "x64" }, "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw=="],
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="],
+44 -22
View File
@@ -3,9 +3,25 @@
import fs from "node:fs/promises";
import Cap from "@cap.js/server";
import { Elysia, file } from "elysia";
import { transform } from "lightningcss";
const processCSS = async () => {
const raw = await fs.readFile("../../widget/src/src/cap.css", "utf-8");
const { code } = transform({
filename: "cap.css",
code: Buffer.from(raw),
minify: true,
targets: {
chrome: 90 << 16,
firefox: 90 << 16,
safari: 14 << 16,
},
});
return code.toString();
};
const cap = new Cap({
tokens_store_path: ".data/tokensList.json",
tokens_store_path: ".data/tokensList.json",
});
const app = new Elysia();
@@ -13,41 +29,47 @@ const app = new Elysia();
app.get("/", () => file("./index.html"));
app.get("/cap.js", async ({ set }) => {
// in the newest version, the worker is injected into the main file
// by a build script. since we don't have a build script here,
// we'll need to build it ourselves.
// in the newest version, the worker and CSS are injected into the main file
// by a build script. since we don't have a build script here,
// we'll need to build it ourselves.
const main = await fs.readFile("../../widget/src/src/cap.js", "utf-8");
const worker = await fs.readFile("../../widget/src/src/worker.js", "utf-8");
const main = await fs.readFile("../../widget/src/src/cap.js", "utf-8");
const worker = await fs.readFile("../../widget/src/src/worker.js", "utf-8");
const css = await processCSS();
const bundle = main.replace("%%workerScript%%", worker);
const bundle = main.replace("%%workerScript%%", worker).replace("%%capCSS%%", css);
set.headers = {
"Content-Type": "application/javascript",
};
set.headers = {
"Content-Type": "application/javascript",
};
return bundle;
return bundle;
});
app.get("/cap-floating.js", () => file("../../widget/src/src/cap-floating.js"));
app.get("/cap.css", async ({ set }) => {
set.headers = { "Content-Type": "text/css" };
return processCSS();
});
app.post("/api/challenge", () => cap.createChallenge());
app.post("/api/redeem", async ({ body, set }) => {
const { token, solutions } = body;
if (!token || !solutions) {
set.status = 400;
return { success: false };
}
const { token, solutions } = body;
if (!token || !solutions) {
set.status = 400;
return { success: false };
}
const answer = await cap.redeemChallenge({ token, solutions });
const answer = await cap.redeemChallenge({ token, solutions });
console.log("new challenge redeemed", {
...answer,
isValid: (await cap.validateToken(answer.token)).success,
});
console.log("new challenge redeemed", {
...answer,
isValid: (await cap.validateToken(answer.token)).success,
});
return answer;
return answer;
});
app.listen(3000);
+2 -1
View File
@@ -12,6 +12,7 @@
},
"dependencies": {
"@cap.js/server": "^1.0.13",
"elysia": "^1.3.4"
"elysia": "^1.3.4",
"lightningcss": "^1.31.1"
}
}
+28
View File
@@ -1,11 +1,13 @@
{
"lockfileVersion": 1,
"configVersion": 0,
"workspaces": {
"": {
"name": "cap-demo",
"dependencies": {
"@cap.js/server": "^1.0.13",
"elysia": "^1.3.4",
"lightningcss": "^1.31.1",
},
},
},
@@ -24,6 +26,8 @@
"debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
"elysia": ["elysia@1.3.4", "", { "dependencies": { "cookie": "^1.0.2", "exact-mirror": "0.1.2", "fast-decode-uri-component": "^1.0.1" }, "optionalDependencies": { "@sinclair/typebox": "^0.34.33", "openapi-types": "^12.1.3" }, "peerDependencies": { "file-type": ">= 20.0.0", "typescript": ">= 5.0.0" } }, "sha512-kAfM3Zwovy3z255IZgTKVxBw91HbgKhYl3TqrGRdZqqr+Fd+4eKOfvxgaKij22+MZLczPzIHtscAmvfpI3+q/A=="],
"exact-mirror": ["exact-mirror@0.1.2", "", { "peerDependencies": { "@sinclair/typebox": "^0.34.15" }, "optionalPeers": ["@sinclair/typebox"] }, "sha512-wFCPCDLmHbKGUb8TOi/IS7jLsgR8WVDGtDK3CzcB4Guf/weq7G+I+DkXiRSZfbemBFOxOINKpraM6ml78vo8Zw=="],
@@ -36,6 +40,30 @@
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
"lightningcss": ["lightningcss@1.31.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.31.1", "lightningcss-darwin-arm64": "1.31.1", "lightningcss-darwin-x64": "1.31.1", "lightningcss-freebsd-x64": "1.31.1", "lightningcss-linux-arm-gnueabihf": "1.31.1", "lightningcss-linux-arm64-gnu": "1.31.1", "lightningcss-linux-arm64-musl": "1.31.1", "lightningcss-linux-x64-gnu": "1.31.1", "lightningcss-linux-x64-musl": "1.31.1", "lightningcss-win32-arm64-msvc": "1.31.1", "lightningcss-win32-x64-msvc": "1.31.1" } }, "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ=="],
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.31.1", "", { "os": "android", "cpu": "arm64" }, "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg=="],
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.31.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg=="],
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.31.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA=="],
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.31.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A=="],
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.31.1", "", { "os": "linux", "cpu": "arm" }, "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g=="],
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.31.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg=="],
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.31.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg=="],
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.31.1", "", { "os": "linux", "cpu": "x64" }, "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA=="],
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.31.1", "", { "os": "linux", "cpu": "x64" }, "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA=="],
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.31.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w=="],
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.31.1", "", { "os": "win32", "cpu": "x64" }, "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw=="],
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="],
+86 -69
View File
@@ -1,8 +1,24 @@
import { Database } from "bun:sqlite";
import fs from "node:fs/promises";
import { Elysia, file } from "elysia";
import { transform } from "lightningcss";
import Cap from "../../server/index.js";
const processCSS = async () => {
const raw = await fs.readFile("../../widget/src/src/cap.css", "utf-8");
const { code } = transform({
filename: "cap.css",
code: Buffer.from(raw),
minify: true,
targets: {
chrome: 90 << 16,
firefox: 90 << 16,
safari: 14 << 16,
},
});
return code.toString();
};
const db = new Database("./.data/cap.db");
db.exec(`
@@ -18,56 +34,51 @@ db.exec(`
`);
const cap = new Cap({
storage: {
challenges: {
store: async (token, challengeData) => {
db.prepare(
"INSERT OR REPLACE INTO challenges (token, data, expires) VALUES (?, ?, ?)",
).run(
token,
JSON.stringify(challengeData.challenge),
challengeData.expires,
);
},
read: async (token) => {
const row = db
.prepare(
"SELECT data, expires FROM challenges WHERE token = ? AND expires > ?",
)
.get(token, Date.now());
storage: {
challenges: {
store: async (token, challengeData) => {
db.prepare("INSERT OR REPLACE INTO challenges (token, data, expires) VALUES (?, ?, ?)").run(
token,
JSON.stringify(challengeData.challenge),
challengeData.expires,
);
},
read: async (token) => {
const row = db
.prepare("SELECT data, expires FROM challenges WHERE token = ? AND expires > ?")
.get(token, Date.now());
return row
? { challenge: JSON.parse(row.data), expires: row.expires }
: null;
},
delete: async (token) => {
db.prepare("DELETE FROM challenges WHERE token = ?").run(token);
},
deleteExpired: async () => {
db.prepare("DELETE FROM challenges WHERE expires <= ?").run(Date.now());
},
},
tokens: {
store: async (tokenKey, expires) => {
db.prepare(
"INSERT OR REPLACE INTO tokens (key, expires) VALUES (?, ?)",
).run(tokenKey, expires);
},
get: async (tokenKey) => {
const row = db
.prepare("SELECT expires FROM tokens WHERE key = ? AND expires > ?")
.get(tokenKey, Date.now());
return row ? { challenge: JSON.parse(row.data), expires: row.expires } : null;
},
delete: async (token) => {
db.prepare("DELETE FROM challenges WHERE token = ?").run(token);
},
deleteExpired: async () => {
db.prepare("DELETE FROM challenges WHERE expires <= ?").run(Date.now());
},
},
tokens: {
store: async (tokenKey, expires) => {
db.prepare("INSERT OR REPLACE INTO tokens (key, expires) VALUES (?, ?)").run(
tokenKey,
expires,
);
},
get: async (tokenKey) => {
const row = db
.prepare("SELECT expires FROM tokens WHERE key = ? AND expires > ?")
.get(tokenKey, Date.now());
return row ? row.expires : null;
},
delete: async (tokenKey) => {
db.prepare("DELETE FROM tokens WHERE key = ?").run(tokenKey);
},
deleteExpired: async () => {
db.prepare("DELETE FROM tokens WHERE expires <= ?").run(Date.now());
},
},
},
return row ? row.expires : null;
},
delete: async (tokenKey) => {
db.prepare("DELETE FROM tokens WHERE key = ?").run(tokenKey);
},
deleteExpired: async () => {
db.prepare("DELETE FROM tokens WHERE expires <= ?").run(Date.now());
},
},
},
});
const app = new Elysia();
@@ -75,41 +86,47 @@ const app = new Elysia();
app.get("/", () => file("./index.html"));
app.get("/cap.js", async ({ set }) => {
// in the newest version, the worker is injected into the main file
// by a build script. since we don't have a build script here,
// we'll need to run a minimal build ourselves.
// in the newest version, the worker and CSS are injected into the main file
// by a build script. since we don't have a build script here,
// we'll need to run a minimal build ourselves.
const main = await fs.readFile("../../widget/src/src/cap.js", "utf-8");
const worker = await fs.readFile("../../widget/src/src/worker.js", "utf-8");
const main = await fs.readFile("../../widget/src/src/cap.js", "utf-8");
const worker = await fs.readFile("../../widget/src/src/worker.js", "utf-8");
const css = await processCSS();
const bundle = main.replace("%%workerScript%%", worker);
const bundle = main.replace("%%workerScript%%", worker).replace("%%capCSS%%", css);
set.headers = {
"Content-Type": "application/javascript",
};
set.headers = {
"Content-Type": "application/javascript",
};
return bundle;
return bundle;
});
app.get("/cap-floating.js", () => file("../../widget/src/src/cap-floating.js"));
app.get("/cap.css", async ({ set }) => {
set.headers = { "Content-Type": "text/css" };
return processCSS();
});
app.post("/api/challenge", () => cap.createChallenge());
app.post("/api/redeem", async ({ body, set }) => {
const { token, solutions } = body;
if (!token || !solutions) {
set.status = 400;
return { success: false };
}
const { token, solutions } = body;
if (!token || !solutions) {
set.status = 400;
return { success: false };
}
const answer = await cap.redeemChallenge({ token, solutions });
const answer = await cap.redeemChallenge({ token, solutions });
console.log("new challenge redeemed", {
...answer,
isValid: (await cap.validateToken(answer.token)).success,
});
console.log("new challenge redeemed", {
...answer,
isValid: (await cap.validateToken(answer.token)).success,
});
return answer;
return answer;
});
app.listen(3000);
+2 -1
View File
@@ -12,6 +12,7 @@
},
"dependencies": {
"@cap.js/server": "^1.0.13",
"elysia": "^1.3.4"
"elysia": "^1.3.4",
"lightningcss": "^1.31.1"
}
}
+1 -1
View File
@@ -128,7 +128,7 @@ export default withMermaid({
[
"script",
{
src: "https://cdn.jsdelivr.net/npm/@cap.js/widget@0.1.35",
src: "https://cdn.jsdelivr.net/npm/@cap.js/widget@0.1.36",
async: true,
},
],
+76 -59
View File
@@ -1,44 +1,61 @@
import fs from "node:fs/promises";
import { transform } from "lightningcss";
import { chromium } from "playwright";
import { minify } from "terser";
const min = async (input) => {
return (
await minify(input, {
compress: {
drop_console: false,
dead_code: true,
reduce_vars: true,
},
output: {
beautify: false,
comments: false,
},
mangle: true,
})
).code
.split("\\n")
.map((e) => {
return e.trimStart();
})
.join("\\n");
const minifyCSS = (input) => {
const { code } = transform({
filename: "cap.css",
code: Buffer.from(input),
minify: true,
targets: {
chrome: 90 << 16,
firefox: 90 << 16,
safari: 14 << 16,
},
});
return code.toString();
};
const minifyJS = async (input) => {
return (
await minify(input, {
compress: {
drop_console: false,
dead_code: true,
reduce_vars: true,
},
output: {
beautify: false,
comments: false,
},
mangle: true,
})
).code
.split("\n")
.map((e) => {
return e.trimStart();
})
.join("\n");
};
console.time("build");
const rawMain = await fs.readFile("./src/src/cap.js", "utf-8");
const minifiedWorker = await min(
await fs.readFile("./src/src/worker.js", "utf-8"),
);
const rawCSS = await fs.readFile("./src/src/cap.css", "utf-8");
const minifiedWorker = await minifyJS(await fs.readFile("./src/src/worker.js", "utf-8"));
const minifiedCSS = minifyCSS(rawCSS);
const bundle = rawMain.replace("%%workerScript%%", minifiedWorker);
const bundle = rawMain
.replace("%%workerScript%%", minifiedWorker)
.replace("%%capCSS%%", minifiedCSS);
await fs.writeFile("./src/cap.min.js", bundle);
await fs.writeFile("./src/cap.min.js", await min(bundle));
await fs.writeFile("./src/cap.min.js", await minifyJS(bundle));
await fs.writeFile(
"./src/cap-floating.min.js",
await min(await fs.readFile("./src/src/cap-floating.js", "utf-8")),
"./src/cap-floating.min.js",
await minifyJS(await fs.readFile("./src/src/cap-floating.js", "utf-8")),
);
console.timeEnd("build");
@@ -49,42 +66,42 @@ const browser = await chromium.launch({ headless: false });
const page = await browser.newPage();
const server = Bun.serve({
port: 3006,
routes: {
"/": () => {
return new Response(Bun.file("./test.html"));
},
"/widget.js": () => {
return new Response(Bun.file("./src/cap.min.js"), {
headers: {
"Content-Type": "application/javascript",
},
});
},
"/failed": () => {
console.error("test failed, quitting");
process.exit(1);
},
"/solved": async () => {
await page.close();
await browser.close();
port: 3006,
routes: {
"/": () => {
return new Response(Bun.file("./test.html"));
},
"/widget.js": () => {
return new Response(Bun.file("./src/cap.min.js"), {
headers: {
"Content-Type": "application/javascript",
},
});
},
"/failed": () => {
console.error("test failed, quitting");
process.exit(1);
},
"/solved": async () => {
await page.close();
await browser.close();
console.timeEnd("test");
server.stop();
console.timeEnd("test");
server.stop();
const publish = prompt("\npublish package to npm? (y/N)");
const publish = prompt("\npublish package to npm? (y/N)");
if (publish === "y") {
Bun.spawn({
cmd: ["bun", "publish", "--access", "public"],
cwd: "./src",
stdout: "inherit",
});
}
if (publish === "y") {
Bun.spawn({
cmd: ["bun", "publish", "--access", "public"],
cwd: "./src",
stdout: "inherit",
});
}
process.exit(0);
},
},
process.exit(0);
},
},
});
page.goto(`http://localhost:3006/`);
+28
View File
@@ -1,9 +1,11 @@
{
"lockfileVersion": 1,
"configVersion": 0,
"workspaces": {
"": {
"name": "widget",
"dependencies": {
"lightningcss": "^1.31.1",
"playwright": "^1.52.0",
"terser": "^5.43.1",
},
@@ -42,8 +44,34 @@
"commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="],
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
"fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="],
"lightningcss": ["lightningcss@1.31.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.31.1", "lightningcss-darwin-arm64": "1.31.1", "lightningcss-darwin-x64": "1.31.1", "lightningcss-freebsd-x64": "1.31.1", "lightningcss-linux-arm-gnueabihf": "1.31.1", "lightningcss-linux-arm64-gnu": "1.31.1", "lightningcss-linux-arm64-musl": "1.31.1", "lightningcss-linux-x64-gnu": "1.31.1", "lightningcss-linux-x64-musl": "1.31.1", "lightningcss-win32-arm64-msvc": "1.31.1", "lightningcss-win32-x64-msvc": "1.31.1" } }, "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ=="],
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.31.1", "", { "os": "android", "cpu": "arm64" }, "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg=="],
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.31.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg=="],
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.31.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA=="],
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.31.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A=="],
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.31.1", "", { "os": "linux", "cpu": "arm" }, "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g=="],
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.31.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg=="],
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.31.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg=="],
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.31.1", "", { "os": "linux", "cpu": "x64" }, "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA=="],
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.31.1", "", { "os": "linux", "cpu": "x64" }, "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA=="],
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.31.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w=="],
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.31.1", "", { "os": "win32", "cpu": "x64" }, "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw=="],
"playwright": ["playwright@1.52.0", "", { "dependencies": { "playwright-core": "1.52.0" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": { "playwright": "cli.js" } }, "sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw=="],
"playwright-core": ["playwright-core@1.52.0", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg=="],
+1
View File
@@ -8,6 +8,7 @@
"typescript": "^5"
},
"dependencies": {
"lightningcss": "^1.31.1",
"playwright": "^1.52.0",
"terser": "^5.43.1"
}
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@cap.js/widget",
"version": "0.1.35",
"version": "0.1.36",
"description": "Client-side widget for Cap, a lightweight, modern open-source CAPTCHA alternative designed using SHA-256 PoW.",
"keywords": [
"security",
+231
View File
@@ -0,0 +1,231 @@
@media (prefers-reduced-motion: reduce) {
.captcha,
.captcha * {
transition: none !important;
animation: none !important;
}
.label {
transition: none !important;
transform: none !important;
filter: none !important;
opacity: 1 !important;
}
.label:not(.active) {
display: none !important;
}
.label.exit {
display: none !important;
}
}
.captcha,
.captcha * {
box-sizing: border-box;
}
.captcha {
background-color: var(--cap-background, #fdfdfd);
border: 1px solid var(--cap-border-color, #dddddd8f);
border-radius: var(--cap-border-radius, 14px);
user-select: none;
height: var(--cap-widget-height, 58px);
width: var(--cap-widget-width, 260px);
display: flex;
align-items: center;
padding: var(--cap-widget-padding, 14px);
gap: var(--cap-gap, 15px);
cursor: pointer;
transition:
filter 0.2s,
transform 0.2s;
position: relative;
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
overflow: hidden;
color: var(--cap-color, #212121);
}
.captcha:hover {
filter: brightness(98%);
}
.captcha * {
font-family: var(
--cap-font,
system,
-apple-system,
"BlinkMacSystemFont",
".SFNSText-Regular",
"San Francisco",
"Roboto",
"Segoe UI",
"Helvetica Neue",
"Lucida Grande",
"Ubuntu",
"arial",
sans-serif
);
}
.checkbox {
width: var(--cap-checkbox-size, 25px);
height: var(--cap-checkbox-size, 25px);
border: var(--cap-checkbox-border, 1px solid #aaaaaad1);
border-radius: var(--cap-checkbox-border-radius, 6px);
background-color: var(--cap-checkbox-background, #fafafa91);
transition: opacity 0.2s;
margin-top: var(--cap-checkbox-margin, 2px);
margin-bottom: var(--cap-checkbox-margin, 2px);
}
.captcha p {
margin: 0;
font-weight: 500;
font-size: 15px;
user-select: none;
}
.label-wrapper {
position: relative;
height: 2em;
overflow: hidden;
flex: 1;
min-width: 0;
display: flex;
align-items: center;
}
.label-wrapper::before,
.label-wrapper::after {
content: "";
pointer-events: none;
position: absolute;
left: 0;
width: 100%;
height: 0.6em;
z-index: 1;
}
.label-wrapper::before {
top: 0;
background: linear-gradient(to bottom, var(--cap-background, #fdfdfd), transparent);
}
.label-wrapper::after {
bottom: 0;
background: linear-gradient(to top, var(--cap-background, #fdfdfd), transparent);
}
.label {
position: absolute;
white-space: nowrap;
opacity: 0;
transform: translateY(100%);
transition:
transform 0.5s cubic-bezier(0.25, 1, 0.5, 1),
opacity 0.5s ease,
filter 0.5s ease;
filter: blur(2px);
}
.label.active {
opacity: 1;
transform: translateY(0);
filter: none;
}
.label.exit {
opacity: 0;
transform: translateY(-100%);
filter: blur(2px);
}
.checkbox .progress-ring {
display: none;
width: 100%;
height: 100%;
transform: rotate(-90deg);
}
.checkbox .progress-ring-bg {
fill: none;
stroke: var(--cap-spinner-background-color, #eee);
stroke-width: var(--cap-spinner-thickness, 3);
}
.checkbox .progress-ring-circle {
fill: none;
stroke: var(--cap-spinner-color, #000);
stroke-width: var(--cap-spinner-thickness, 3);
stroke-linecap: round;
stroke-dasharray: 87.96;
stroke-dashoffset: 87.96;
transition: stroke-dashoffset 0.3s ease;
}
.captcha[data-state="verifying"] .checkbox {
background: none;
display: flex;
align-items: center;
justify-content: center;
transform: scale(1.1);
border: none;
border-radius: 50%;
background-color: transparent;
}
.captcha[data-state="verifying"] .checkbox .progress-ring {
display: block;
}
.captcha[data-state="done"] .checkbox {
border: 1px solid transparent;
background-image: var(
--cap-checkmark,
url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cstyle%3E%40keyframes%20anim%7B0%25%7Bstroke-dashoffset%3A23.21320343017578px%7Dto%7Bstroke-dashoffset%3A0%7D%7D%3C%2Fstyle%3E%3Cpath%20fill%3D%22none%22%20stroke%3D%22%2300a67d%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%20stroke-width%3D%222%22%20d%3D%22m5%2012%205%205L20%207%22%20style%3D%22stroke-dashoffset%3A0%3Bstroke-dasharray%3A23.21320343017578px%3Banimation%3Aanim%20.5s%20ease%22%2F%3E%3C%2Fsvg%3E")
);
background-size: cover;
}
.captcha[data-state="done"] .checkbox .progress-ring {
display: none;
}
.captcha[data-state="error"] .checkbox {
border: 1px solid transparent;
background-image: var(
--cap-error-cross,
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='96' height='96' viewBox='0 0 24 24'%3E%3Cpath fill='%23f55b50' d='M11 15h2v2h-2zm0-8h2v6h-2zm1-5C6.47 2 2 6.5 2 12a10 10 0 0 0 10 10a10 10 0 0 0 10-10A10 10 0 0 0 12 2m0 18a8 8 0 0 1-8-8a8 8 0 0 1 8-8a8 8 0 0 1 8 8a8 8 0 0 1-8 8'/%3E%3C%2Fsvg%3E")
);
background-size: cover;
}
.captcha[data-state="error"] .checkbox .progress-ring {
display: none;
}
.captcha[disabled] {
cursor: not-allowed;
}
.captcha[disabled][data-state="verifying"] {
cursor: progress;
}
.captcha[disabled][data-state="done"] {
cursor: default;
}
.captcha .credits {
position: absolute;
bottom: 10px;
right: 10px;
font-size: 12px;
color: var(--cap-color, #212121);
opacity: 0.8;
text-underline-offset: 0.18em;
text-decoration-thickness: 0.08em;
z-index: 6;
}
+622 -578
View File
File diff suppressed because it is too large Load Diff
+164 -95
View File
@@ -1,115 +1,184 @@
(() => {
const solveFallback = async ({ salt, target }) => {
let nonce = 0;
const batchSize = 50000;
const encoder = new TextEncoder();
const solveFallback = async ({ salt, target }) => {
let nonce = 0;
const batchSize = 50000;
const encoder = new TextEncoder();
const targetBytes = new Uint8Array(target.length / 2);
for (let k = 0; k < targetBytes.length; k++) {
targetBytes[k] = parseInt(target.substring(k * 2, k * 2 + 2), 16);
}
const targetBytesLength = targetBytes.length;
const targetBytes = new Uint8Array(target.length / 2);
for (let k = 0; k < targetBytes.length; k++) {
targetBytes[k] = parseInt(target.substring(k * 2, k * 2 + 2), 16);
}
const targetBytesLength = targetBytes.length;
while (true) {
try {
for (let i = 0; i < batchSize; i++) {
const inputString = salt + nonce;
const inputBytes = encoder.encode(inputString);
while (true) {
try {
for (let i = 0; i < batchSize; i++) {
const inputString = salt + nonce;
const inputBytes = encoder.encode(inputString);
const hashBuffer = await crypto.subtle.digest("SHA-256", inputBytes);
const hashBuffer = await crypto.subtle.digest("SHA-256", inputBytes);
const hashBytes = new Uint8Array(hashBuffer, 0, targetBytesLength);
const hashBytes = new Uint8Array(hashBuffer, 0, targetBytesLength);
let matches = true;
for (let k = 0; k < targetBytesLength; k++) {
if (hashBytes[k] !== targetBytes[k]) {
matches = false;
break;
}
}
let matches = true;
for (let k = 0; k < targetBytesLength; k++) {
if (hashBytes[k] !== targetBytes[k]) {
matches = false;
break;
}
}
if (matches) {
self.postMessage({ nonce, found: true });
return;
}
if (matches) {
self.postMessage({ nonce, found: true });
return;
}
nonce++;
}
} catch (error) {
console.error("[cap worker]", error);
self.postMessage({
found: false,
error: error.message,
});
return;
}
}
};
nonce++;
}
} catch (error) {
console.error("[cap worker]", error);
self.postMessage({
found: false,
error: error.message,
});
return;
}
}
};
if (
typeof WebAssembly !== "object" ||
typeof WebAssembly?.instantiate !== "function"
) {
console.warn(
"[cap worker] wasm not supported, falling back to alternative solver. this will be significantly slower.",
);
if (typeof WebAssembly !== "object" || typeof WebAssembly?.instantiate !== "function") {
console.warn(
"[cap worker] wasm not supported, falling back to alternative solver. this will be significantly slower.",
);
self.onmessage = async ({ data: { salt, target } }) => {
return solveFallback({ salt, target });
};
self.onmessage = async ({ data: { salt, target } }) => {
return solveFallback({ salt, target });
};
return;
}
return;
}
let wasmCacheUrl, solve_pow_function;
let solve_pow_function = null;
self.onmessage = async ({ data: { salt, target, wasmUrl } }) => {
let fb;
const initFromModule = (wasmModule) => {
try {
let wasm;
let WASM_VECTOR_LEN = 0;
let cachedUint8ArrayMemory = null;
if (wasmCacheUrl !== wasmUrl) {
wasmCacheUrl = wasmUrl;
await import(wasmUrl)
.then((wasmModule) => {
return wasmModule.default().then((instance) => {
solve_pow_function = (
instance?.exports ? instance.exports : wasmModule
).solve_pow;
});
})
.catch((e) => {
console.error("[cap worker] using fallback solver due to error:", e);
fb = true;
const getMemory = () => {
if (cachedUint8ArrayMemory === null || cachedUint8ArrayMemory.byteLength === 0) {
cachedUint8ArrayMemory = new Uint8Array(wasm.memory.buffer);
}
return cachedUint8ArrayMemory;
};
return solveFallback({ salt, target });
});
const encoder = new TextEncoder();
if (fb) return;
}
const passStringToWasm = (str, malloc, realloc) => {
if (realloc === undefined) {
const encoded = encoder.encode(str);
const ptr = malloc(encoded.length, 1) >>> 0;
getMemory()
.subarray(ptr, ptr + encoded.length)
.set(encoded);
WASM_VECTOR_LEN = encoded.length;
return ptr;
}
try {
const startTime = performance.now();
const nonce = solve_pow_function(salt, target);
const endTime = performance.now();
let len = str.length;
let ptr = malloc(len, 1) >>> 0;
const mem = getMemory();
let offset = 0;
self.postMessage({
nonce: Number(nonce),
found: true,
durationMs: (endTime - startTime).toFixed(2),
});
} catch (error) {
console.error("[cap worker]", error);
self.postMessage({
found: false,
error: error.message || String(error),
});
}
};
for (; offset < len; offset++) {
const code = str.charCodeAt(offset);
if (code > 127) break;
mem[ptr + offset] = code;
}
self.onerror = (error) => {
self.postMessage({
found: false,
error,
});
};
if (offset !== len) {
if (offset !== 0) str = str.slice(offset);
ptr = realloc(ptr, len, (len = offset + str.length * 3), 1) >>> 0;
const subarray = getMemory().subarray(ptr + offset, ptr + len);
const { written } = encoder.encodeInto(str, subarray);
offset += written;
ptr = realloc(ptr, len, offset, 1) >>> 0;
}
WASM_VECTOR_LEN = offset;
return ptr;
};
const imports = { wbg: {} };
imports.wbg.__wbindgen_init_externref_table = () => {
const table = wasm.__wbindgen_export_0;
const offset = table.grow(4);
table.set(0, undefined);
table.set(offset + 0, undefined);
table.set(offset + 1, null);
table.set(offset + 2, true);
table.set(offset + 3, false);
};
const instance = new WebAssembly.Instance(wasmModule, imports);
wasm = instance.exports;
if (wasm.__wbindgen_start) wasm.__wbindgen_start();
solve_pow_function = (salt, target) => {
const saltPtr = passStringToWasm(salt, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const saltLen = WASM_VECTOR_LEN;
const targetPtr = passStringToWasm(target, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const targetLen = WASM_VECTOR_LEN;
return BigInt.asUintN(64, wasm.solve_pow(saltPtr, saltLen, targetPtr, targetLen));
};
return true;
} catch (e) {
console.error("[cap worker] failed to init wasm from module:", e);
return false;
}
};
self.onmessage = async ({ data: { salt, target, wasmModule } }) => {
if (wasmModule instanceof WebAssembly.Module && solve_pow_function === null) {
const ok = initFromModule(wasmModule);
if (!ok) {
console.warn("[cap worker] wasm init failed, falling back to JS solver.");
return solveFallback({ salt, target });
}
}
if (solve_pow_function === null) {
console.warn("[cap worker] no wasm module provided, falling back to JS solver.");
return solveFallback({ salt, target });
}
try {
const startTime = performance.now();
const nonce = solve_pow_function(salt, target);
const endTime = performance.now();
self.postMessage({
nonce: Number(nonce),
found: true,
durationMs: (endTime - startTime).toFixed(2),
});
} catch (error) {
console.error("[cap worker]", error);
self.postMessage({
found: false,
error: error.message || String(error),
});
}
};
self.onerror = (error) => {
self.postMessage({
found: false,
error,
});
};
})();
+1 -26
View File
@@ -359,26 +359,6 @@
});
});
// ====================================================
// this is a now unused library which an old version of
// cap depended on. to avoid breaking things as much as
// possible, we've kept it here.
try {
// lets us know how many people are actually using this
// so we can know when it's safe to deprecate.
// server source code:
// https://gist.github.com/tiagozip/ffb39489f5af91e6e45f94f1bfa14ab2
fetch(
`https://api.tiagorangel.com/cap-legacy-widget?h=${self.location?.hostname || "unknown"}`,
{
mode: "no-cors",
},
).catch(() => {});
} catch {}
console.warn(
`[cap]
%cYou're using a deprecated version of Cap's widget that still relies on this file.
@@ -387,9 +367,4 @@ It may continue to work for now, but could break at any time since this dependen
Please update Cap to fix this.`,
"font-size:15px;background-image:url('https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fpreview.colorkit.co%2Fcolor%2FEEEEEE.png%3Ftype%3Darticle-preview-logo%26size%3Dsocial%26colorname%3DSuper%2520Silver&f=1&nofb=1&ipt=49845e9195461b7c779182793c2ebf7834102eaf5561c15fa2cbb55494b77a9b');background-size:10px",
);
console.log(
`%cTo help us understand how many people are using this legacy version and when it's safe to deprecate it, we've sent a small, privacy-friendly beacon to our servers. All related code, including the telemetry server, is open source.\n\nYou might have gotten a CSP error before this, it should be safe to ignore. Server source code: https://gist.github.com/tiagozip/ffb39489f5af91e6e45f94f1bfa14ab2`,
"font-size:11px;color:#b7b7b7",
);
);