widget(0.1.36): better widget ui
This commit is contained in:
@@ -15,3 +15,7 @@ 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
|
||||
|
||||
## current roadmap
|
||||
|
||||
javascript challenges and reputation-based difficulties are the main new feature focus.
|
||||
|
||||
@@ -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=="],
|
||||
|
||||
@@ -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 }) => {
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@cap.js/server": "^1.0.13",
|
||||
"elysia": "^1.3.4"
|
||||
"elysia": "^1.3.4",
|
||||
"lightningcss": "^1.31.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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=="],
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@cap.js/server": "latest",
|
||||
"elysia": "^1.3.3"
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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=="],
|
||||
}
|
||||
}
|
||||
@@ -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`);
|
||||
});
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@cap.js/server": "latest",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"express": "^5.1.0"
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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=="],
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@cap.js/server": "latest",
|
||||
"hono": "^4.7.10"
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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
@@ -3,6 +3,22 @@
|
||||
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",
|
||||
@@ -13,14 +29,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 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 css = await processCSS();
|
||||
|
||||
const bundle = main.replace("%%workerScript%%", worker);
|
||||
const bundle = main.replace("%%workerScript%%", worker).replace("%%capCSS%%", css);
|
||||
|
||||
set.headers = {
|
||||
"Content-Type": "application/javascript",
|
||||
@@ -31,6 +48,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 }) => {
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@cap.js/server": "^1.0.13",
|
||||
"elysia": "^1.3.4"
|
||||
"elysia": "^1.3.4",
|
||||
"lightningcss": "^1.31.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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=="],
|
||||
|
||||
+31
-14
@@ -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(`
|
||||
@@ -21,9 +37,7 @@ const cap = new Cap({
|
||||
storage: {
|
||||
challenges: {
|
||||
store: async (token, challengeData) => {
|
||||
db.prepare(
|
||||
"INSERT OR REPLACE INTO challenges (token, data, expires) VALUES (?, ?, ?)",
|
||||
).run(
|
||||
db.prepare("INSERT OR REPLACE INTO challenges (token, data, expires) VALUES (?, ?, ?)").run(
|
||||
token,
|
||||
JSON.stringify(challengeData.challenge),
|
||||
challengeData.expires,
|
||||
@@ -31,14 +45,10 @@ const cap = new Cap({
|
||||
},
|
||||
read: async (token) => {
|
||||
const row = db
|
||||
.prepare(
|
||||
"SELECT data, expires FROM challenges WHERE token = ? AND expires > ?",
|
||||
)
|
||||
.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;
|
||||
return row ? { challenge: JSON.parse(row.data), expires: row.expires } : null;
|
||||
},
|
||||
delete: async (token) => {
|
||||
db.prepare("DELETE FROM challenges WHERE token = ?").run(token);
|
||||
@@ -49,9 +59,10 @@ const cap = new Cap({
|
||||
},
|
||||
tokens: {
|
||||
store: async (tokenKey, expires) => {
|
||||
db.prepare(
|
||||
"INSERT OR REPLACE INTO tokens (key, expires) VALUES (?, ?)",
|
||||
).run(tokenKey, expires);
|
||||
db.prepare("INSERT OR REPLACE INTO tokens (key, expires) VALUES (?, ?)").run(
|
||||
tokenKey,
|
||||
expires,
|
||||
);
|
||||
},
|
||||
get: async (tokenKey) => {
|
||||
const row = db
|
||||
@@ -75,14 +86,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",
|
||||
@@ -93,6 +105,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 }) => {
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@cap.js/server": "^1.0.13",
|
||||
"elysia": "^1.3.4"
|
||||
"elysia": "^1.3.4",
|
||||
"lightningcss": "^1.31.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
],
|
||||
|
||||
+26
-9
@@ -1,8 +1,23 @@
|
||||
import fs from "node:fs/promises";
|
||||
import { transform } from "lightningcss";
|
||||
import { chromium } from "playwright";
|
||||
import { minify } from "terser";
|
||||
|
||||
const min = async (input) => {
|
||||
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: {
|
||||
@@ -17,28 +32,30 @@ const min = async (input) => {
|
||||
mangle: true,
|
||||
})
|
||||
).code
|
||||
.split("\\n")
|
||||
.split("\n")
|
||||
.map((e) => {
|
||||
return e.trimStart();
|
||||
})
|
||||
.join("\\n");
|
||||
.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")),
|
||||
await minifyJS(await fs.readFile("./src/src/cap-floating.js", "utf-8")),
|
||||
);
|
||||
|
||||
console.timeEnd("build");
|
||||
|
||||
@@ -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=="],
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"typescript": "^5"
|
||||
},
|
||||
"dependencies": {
|
||||
"lightningcss": "^1.31.1",
|
||||
"playwright": "^1.52.0",
|
||||
"terser": "^5.43.1"
|
||||
}
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
+148
-104
@@ -5,11 +5,25 @@
|
||||
return;
|
||||
}
|
||||
|
||||
const capFetch = (...args) => {
|
||||
const capFetch = (u, _conf = {}) => {
|
||||
const conf = {
|
||||
..._conf,
|
||||
headers: {
|
||||
...(_conf.headers || {}),
|
||||
"Cap-Stamp": btoa(
|
||||
String.fromCharCode(
|
||||
...[[Date.now()]].map((n) => [n >> 24, n >> 16, n >> 8, n[0]].map((x) => x & 255))[0],
|
||||
),
|
||||
).replace(/=/g, ""),
|
||||
"Cap-Solver": `0,${WASM_VERSION}`,
|
||||
},
|
||||
};
|
||||
|
||||
if (window?.CAP_CUSTOM_FETCH) {
|
||||
return window.CAP_CUSTOM_FETCH(...args);
|
||||
return window.CAP_CUSTOM_FETCH(u, conf);
|
||||
}
|
||||
return fetch(...args);
|
||||
|
||||
return fetch(u, conf);
|
||||
};
|
||||
|
||||
function prng(seed, length) {
|
||||
@@ -17,8 +31,7 @@
|
||||
let hash = 2166136261;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
hash ^= str.charCodeAt(i);
|
||||
hash +=
|
||||
(hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
|
||||
hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
|
||||
}
|
||||
return hash >>> 0;
|
||||
}
|
||||
@@ -41,20 +54,36 @@
|
||||
return result.substring(0, length);
|
||||
}
|
||||
|
||||
if (!window.CAP_CUSTOM_WASM_URL) {
|
||||
// preloads the wasm files to save up time on solve
|
||||
[
|
||||
`https://cdn.jsdelivr.net/npm/@cap.js/wasm@${WASM_VERSION}/browser/cap_wasm.min.js`,
|
||||
`https://cdn.jsdelivr.net/npm/@cap.js/wasm@${WASM_VERSION}/browser/cap_wasm_bg.wasm`,
|
||||
].forEach((url) => {
|
||||
const link = document.createElement("link");
|
||||
link.rel = "prefetch";
|
||||
link.href = url;
|
||||
link.as = url.endsWith(".wasm") ? "fetch" : "script";
|
||||
document.head.appendChild(link);
|
||||
let wasmModulePromise = null;
|
||||
|
||||
const getWasmModule = () => {
|
||||
if (wasmModulePromise) return wasmModulePromise;
|
||||
|
||||
const wasmUrl =
|
||||
window.CAP_CUSTOM_WASM_URL ||
|
||||
`https://cdn.jsdelivr.net/npm/@cap.js/wasm@${WASM_VERSION}/browser/cap_wasm_bg.wasm`;
|
||||
|
||||
wasmModulePromise = fetch(wasmUrl)
|
||||
.then((r) => {
|
||||
if (!r.ok) throw new Error(`Failed to fetch wasm: ${r.status}`);
|
||||
return r.arrayBuffer();
|
||||
})
|
||||
.then((buf) => WebAssembly.compile(buf))
|
||||
.catch((e) => {
|
||||
wasmModulePromise = null;
|
||||
throw e;
|
||||
});
|
||||
|
||||
return wasmModulePromise;
|
||||
};
|
||||
|
||||
if (typeof WebAssembly === "object" && typeof WebAssembly.compile === "function") {
|
||||
getWasmModule().catch(() => {});
|
||||
}
|
||||
|
||||
const prefersReducedMotion = () =>
|
||||
window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? false;
|
||||
|
||||
class CapWidget extends HTMLElement {
|
||||
#workerUrl = "";
|
||||
#resetTimer = null;
|
||||
@@ -78,7 +107,6 @@
|
||||
"onerror",
|
||||
"data-cap-worker-count",
|
||||
"data-cap-i18n-initial-state",
|
||||
"[cap]",
|
||||
];
|
||||
}
|
||||
|
||||
@@ -134,12 +162,9 @@
|
||||
if (
|
||||
name === "data-cap-i18n-initial-state" &&
|
||||
this.#div &&
|
||||
this.#div?.querySelector("p")?.innerText
|
||||
this.#div?.querySelector(".label.active")
|
||||
) {
|
||||
this.#div.querySelector("p").innerText = this.getI18nText(
|
||||
"initial-state",
|
||||
"Verify you're human",
|
||||
);
|
||||
this.animateLabel(this.getI18nText("initial-state", "Verify you're human"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,8 +180,7 @@
|
||||
const workers = this.getAttribute("data-cap-worker-count");
|
||||
const parsedWorkers = workers ? parseInt(workers, 10) : null;
|
||||
this.setWorkersCount(parsedWorkers || navigator.hardwareConcurrency || 8);
|
||||
const fieldName =
|
||||
this.getAttribute("data-cap-hidden-field-name") || "cap-token";
|
||||
const fieldName = this.getAttribute("data-cap-hidden-field-name") || "cap-token";
|
||||
this.#host.innerHTML = `<input type="hidden" name="${fieldName}">`;
|
||||
}
|
||||
|
||||
@@ -167,18 +191,11 @@
|
||||
|
||||
try {
|
||||
this.#solving = true;
|
||||
this.updateUI(
|
||||
"verifying",
|
||||
this.getI18nText("verifying-label", "Verifying..."),
|
||||
true,
|
||||
);
|
||||
this.updateUI("verifying", this.getI18nText("verifying-label", "Verifying..."), true);
|
||||
|
||||
this.#div.setAttribute(
|
||||
"aria-label",
|
||||
this.getI18nText(
|
||||
"verifying-aria-label",
|
||||
"Verifying you're a human, please wait",
|
||||
),
|
||||
this.getI18nText("verifying-aria-label", "Verifying you're a human, please wait"),
|
||||
);
|
||||
|
||||
this.dispatchEvent("progress", { progress: 0 });
|
||||
@@ -211,10 +228,7 @@
|
||||
challenges = Array.from({ length: challenge.c }, () => {
|
||||
i = i + 1;
|
||||
|
||||
return [
|
||||
prng(`${token}${i}`, challenge.s),
|
||||
prng(`${token}${i}d`, challenge.d),
|
||||
];
|
||||
return [prng(`${token}${i}`, challenge.s), prng(`${token}${i}d`, challenge.d)];
|
||||
});
|
||||
}
|
||||
|
||||
@@ -231,8 +245,7 @@
|
||||
this.dispatchEvent("progress", { progress: 100 });
|
||||
|
||||
if (!resp.success) throw new Error("Invalid solution");
|
||||
const fieldName =
|
||||
this.getAttribute("data-cap-hidden-field-name") || "cap-token";
|
||||
const fieldName = this.getAttribute("data-cap-hidden-field-name") || "cap-token";
|
||||
if (this.querySelector(`input[name='${fieldName}']`)) {
|
||||
this.querySelector(`input[name='${fieldName}']`).value = resp.token;
|
||||
}
|
||||
@@ -260,10 +273,7 @@
|
||||
} catch (err) {
|
||||
this.#div.setAttribute(
|
||||
"aria-label",
|
||||
this.getI18nText(
|
||||
"error-aria-label",
|
||||
"An error occurred, please try again",
|
||||
),
|
||||
this.getI18nText("error-aria-label", "An error occurred, please try again"),
|
||||
);
|
||||
this.error(err.message);
|
||||
throw err;
|
||||
@@ -273,10 +283,39 @@
|
||||
}
|
||||
}
|
||||
|
||||
async solveChallenges(challenge) {
|
||||
const total = challenge.length;
|
||||
async solveChallenges(challenges) {
|
||||
const total = challenges.length;
|
||||
let completed = 0;
|
||||
|
||||
let wasmModule = null;
|
||||
const wasmSupported =
|
||||
typeof WebAssembly === "object" && typeof WebAssembly.instantiate === "function";
|
||||
|
||||
if (wasmSupported) {
|
||||
try {
|
||||
wasmModule = await getWasmModule();
|
||||
} catch (e) {
|
||||
console.warn("[cap] wasm unavailable, falling back to JS solver:", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (!wasmSupported) {
|
||||
if (!this.#shadow.querySelector(".warning")) {
|
||||
const warningEl = document.createElement("div");
|
||||
warningEl.className = "warning";
|
||||
warningEl.style.cssText = `width:var(--cap-widget-width,230px);background:rgb(237,56,46);color:white;padding:4px 6px;padding-bottom:calc(var(--cap-border-radius,14px) + 5px);font-size:10px;box-sizing:border-box;font-family:system-ui;border-top-left-radius:8px;border-top-right-radius:8px;text-align:center;user-select:none;margin-bottom:-35.5px;opacity:0;transition:margin-bottom .3s,opacity .3s;`;
|
||||
warningEl.innerText = this.getI18nText(
|
||||
"wasm-disabled",
|
||||
"Enable WASM for significantly faster solving",
|
||||
);
|
||||
this.#shadow.insertBefore(warningEl, this.#shadow.firstChild);
|
||||
setTimeout(() => {
|
||||
warningEl.style.marginBottom = `calc(-1 * var(--cap-border-radius, 14px))`;
|
||||
warningEl.style.opacity = 1;
|
||||
}, 10);
|
||||
}
|
||||
}
|
||||
|
||||
const workers = Array(this.#workersCount)
|
||||
.fill(null)
|
||||
.map(() => {
|
||||
@@ -312,40 +351,17 @@
|
||||
reject(err);
|
||||
};
|
||||
|
||||
worker.postMessage({
|
||||
salt,
|
||||
target,
|
||||
wasmUrl:
|
||||
window.CAP_CUSTOM_WASM_URL ||
|
||||
`https://cdn.jsdelivr.net/npm/@cap.js/wasm@${WASM_VERSION}/browser/cap_wasm.min.js`,
|
||||
});
|
||||
|
||||
if (
|
||||
typeof WebAssembly !== "object" ||
|
||||
typeof WebAssembly?.instantiate !== "function"
|
||||
) {
|
||||
if (this.#shadow.querySelector(".warning")) return;
|
||||
const warningEl = document.createElement("div");
|
||||
warningEl.className = "warning";
|
||||
warningEl.style.cssText = `width: var(--cap-widget-width, 230px);background: rgb(237, 56, 46);color: white;padding: 4px 6px;padding-bottom: calc(var(--cap-border-radius, 14px) + 5px);font-size: 10px;box-sizing: border-box;font-family: system-ui;border-top-left-radius: 8px;border-top-right-radius: 8px;text-align: center;padding-bottom:calc(var(--cap-border-radius,14px) + 5px);user-select:none;margin-bottom: -35.5px;opacity: 0;transition: margin-bottom .3s,opacity .3s;`;
|
||||
warningEl.innerText =
|
||||
this.getI18nText("wasm-disabled", "Enable WASM for significantly faster solving");
|
||||
this.#shadow.insertBefore(warningEl, this.#shadow.firstChild);
|
||||
|
||||
setTimeout(() => {
|
||||
warningEl.style.marginBottom = `calc(-1 * var(--cap-border-radius, 14px))`
|
||||
warningEl.style.opacity = 1;
|
||||
}, 10);
|
||||
if (wasmModule) {
|
||||
worker.postMessage({ salt, target, wasmModule }, []);
|
||||
} else {
|
||||
worker.postMessage({ salt, target });
|
||||
}
|
||||
});
|
||||
|
||||
const results = [];
|
||||
try {
|
||||
for (let i = 0; i < challenge.length; i += this.#workersCount) {
|
||||
const chunk = challenge.slice(
|
||||
i,
|
||||
Math.min(i + this.#workersCount, challenge.length),
|
||||
);
|
||||
for (let i = 0; i < challenges.length; i += this.#workersCount) {
|
||||
const chunk = challenges.slice(i, Math.min(i + this.#workersCount, challenges.length));
|
||||
const chunkResults = await Promise.all(
|
||||
chunk.map((c, idx) => solveSingleChallenge(c, idx)),
|
||||
);
|
||||
@@ -370,9 +386,7 @@
|
||||
const parsedWorkers = parseInt(workers, 10);
|
||||
const maxWorkers = Math.min(navigator.hardwareConcurrency || 8, 16);
|
||||
this.#workersCount =
|
||||
!Number.isNaN(parsedWorkers) &&
|
||||
parsedWorkers > 0 &&
|
||||
parsedWorkers <= maxWorkers
|
||||
!Number.isNaN(parsedWorkers) && parsedWorkers > 0 && parsedWorkers <= maxWorkers
|
||||
? parsedWorkers
|
||||
: navigator.hardwareConcurrency || 8;
|
||||
}
|
||||
@@ -387,12 +401,14 @@
|
||||
);
|
||||
this.#div.setAttribute("aria-live", "polite");
|
||||
this.#div.setAttribute("disabled", "true");
|
||||
this.#div.innerHTML = `<div class="checkbox" part="checkbox"><svg class="progress-ring" viewBox="0 0 32 32"><circle class="progress-ring-bg" cx="16" cy="16" r="14"></circle><circle class="progress-ring-circle" cx="16" cy="16" r="14"></circle></svg></div><p part="label">${this.getI18nText(
|
||||
this.#div.innerHTML = `<div class="checkbox" part="checkbox"><svg class="progress-ring" viewBox="0 0 32 32"><circle class="progress-ring-bg" cx="16" cy="16" r="14"></circle><circle class="progress-ring-circle" cx="16" cy="16" r="14"></circle></svg></div><p part="label" class="label-wrapper"><span class="label active">${this.getI18nText(
|
||||
"initial-state",
|
||||
"Verify you're human",
|
||||
)}</p><a part="attribution" aria-label="Secured by Cap" href="https://capjs.js.org/" class="credits" target="_blank" rel="follow noopener">Cap</a>`;
|
||||
)}</span></p><a part="attribution" aria-label="Secured by Cap" href="https://capjs.js.org/" class="credits" target="_blank" rel="follow noopener" title="Secured by Cap: Self-hosted CAPTCHA for the modern web.">Cap</a>`;
|
||||
|
||||
this.#shadow.innerHTML = `<style${window.CAP_CSS_NONCE ? ` nonce=${window.CAP_CSS_NONCE}` : ""}>.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 .2s,transform .2s;position:relative;-webkit-tap-highlight-color:rgba(255,255,255,0);overflow:hidden;color:var(--cap-color,#212121)}.captcha:hover{filter:brightness(98%)}.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 .2s;margin-top:var(--cap-checkbox-margin,2px);margin-bottom:var(--cap-checkbox-margin,2px)}.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)}.captcha p{margin:0;font-weight:500;font-size:15px;user-select:none;transition:opacity .2s}.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/svg%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: 1.5px;}</style>`;
|
||||
const css = `%%capCSS%%`;
|
||||
|
||||
this.#shadow.innerHTML = `<style${window.CAP_CSS_NONCE ? ` nonce=${window.CAP_CSS_NONCE}` : ""}>${css}</style>`;
|
||||
|
||||
this.#shadow.appendChild(this.#div);
|
||||
}
|
||||
@@ -411,10 +427,7 @@
|
||||
});
|
||||
|
||||
this.#div.addEventListener("keydown", (e) => {
|
||||
if (
|
||||
(e.key === "Enter" || e.key === " ") &&
|
||||
!this.#div.hasAttribute("disabled")
|
||||
) {
|
||||
if ((e.key === "Enter" || e.key === " ") && !this.#div.hasAttribute("disabled")) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.solve();
|
||||
@@ -427,12 +440,47 @@
|
||||
this.addEventListener("reset", this.boundHandleReset);
|
||||
}
|
||||
|
||||
animateLabel(text) {
|
||||
if (!this.#div) return;
|
||||
const wrapper = this.#div.querySelector(".label-wrapper");
|
||||
if (!wrapper) return;
|
||||
|
||||
if (prefersReducedMotion()) {
|
||||
const current = wrapper.querySelector(".label.active");
|
||||
if (current) {
|
||||
current.textContent = text;
|
||||
} else {
|
||||
const span = document.createElement("span");
|
||||
span.className = "label active";
|
||||
span.textContent = text;
|
||||
wrapper.appendChild(span);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const current = wrapper.querySelector(".label.active");
|
||||
|
||||
const next = document.createElement("span");
|
||||
next.className = "label";
|
||||
next.textContent = text;
|
||||
wrapper.appendChild(next);
|
||||
|
||||
void next.offsetWidth;
|
||||
|
||||
next.classList.add("active");
|
||||
if (current) {
|
||||
current.classList.remove("active");
|
||||
current.classList.add("exit");
|
||||
current.addEventListener("transitionend", () => current.remove(), { once: true });
|
||||
}
|
||||
}
|
||||
|
||||
updateUI(state, text, disabled = false) {
|
||||
if (!this.#div) return;
|
||||
|
||||
this.#div.setAttribute("data-state", state);
|
||||
|
||||
this.#div.querySelector("p").innerText = text;
|
||||
this.animateLabel(text);
|
||||
|
||||
if (disabled) {
|
||||
this.#div.setAttribute("disabled", "true");
|
||||
@@ -444,35 +492,32 @@
|
||||
handleProgress(event) {
|
||||
if (!this.#div) return;
|
||||
|
||||
const progressElement = this.#div.querySelector("p");
|
||||
const progressCircle = this.#div.querySelector(".progress-ring-circle");
|
||||
|
||||
if (progressElement && progressCircle) {
|
||||
if (progressCircle) {
|
||||
const circumference = 2 * Math.PI * 14;
|
||||
const offset = circumference - (event.detail.progress / 100) * circumference;
|
||||
progressCircle.style.strokeDashoffset = offset;
|
||||
progressElement.innerText = `${this.getI18nText(
|
||||
"verifying-label",
|
||||
"Verifying...",
|
||||
)} ${event.detail.progress}%`;
|
||||
}
|
||||
|
||||
const wrapper = this.#div.querySelector(".label-wrapper");
|
||||
if (wrapper) {
|
||||
const activeLabel = wrapper.querySelector(".label.active");
|
||||
if (activeLabel) {
|
||||
activeLabel.textContent = `${this.getI18nText("verifying-label", "Verifying...")} ${event.detail.progress}%`;
|
||||
}
|
||||
}
|
||||
|
||||
this.executeAttributeCode("onprogress", event);
|
||||
}
|
||||
|
||||
handleSolve(event) {
|
||||
this.updateUI(
|
||||
"done",
|
||||
this.getI18nText("solved-label", "You're a human"),
|
||||
true,
|
||||
);
|
||||
this.updateUI("done", this.getI18nText("solved-label", "You're a human"), true);
|
||||
this.executeAttributeCode("onsolve", event);
|
||||
}
|
||||
|
||||
handleError(event) {
|
||||
this.updateUI(
|
||||
"error",
|
||||
this.getI18nText("error-label", "Error. Try again."),
|
||||
);
|
||||
this.updateUI("error", this.getI18nText("error-label", "Error. Try again."));
|
||||
this.executeAttributeCode("onerror", event);
|
||||
}
|
||||
|
||||
@@ -511,8 +556,7 @@
|
||||
}
|
||||
this.dispatchEvent("reset");
|
||||
this.token = null;
|
||||
const fieldName =
|
||||
this.getAttribute("data-cap-hidden-field-name") || "cap-token";
|
||||
const fieldName = this.getAttribute("data-cap-hidden-field-name") || "cap-token";
|
||||
if (this.querySelector(`input[name='${fieldName}']`)) {
|
||||
this.querySelector(`input[name='${fieldName}']`).value = "";
|
||||
}
|
||||
@@ -554,7 +598,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Invisible
|
||||
class Cap {
|
||||
constructor(config = {}, el) {
|
||||
const widget = el || document.createElement("cap-widget");
|
||||
@@ -591,11 +634,12 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.Cap = Cap;
|
||||
|
||||
if (!customElements.get("cap-widget") && !window?.CAP_DONT_SKIP_REDEFINE) {
|
||||
customElements.define("cap-widget", CapWidget);
|
||||
} else {
|
||||
} else if (customElements.get("cap-widget")) {
|
||||
console.warn(
|
||||
"[cap] the cap-widget element has already been defined, skipping re-defining it.\nto prevent this, set window.CAP_DONT_SKIP_REDEFINE to true",
|
||||
);
|
||||
|
||||
+91
-22
@@ -46,10 +46,7 @@
|
||||
}
|
||||
};
|
||||
|
||||
if (
|
||||
typeof WebAssembly !== "object" ||
|
||||
typeof WebAssembly?.instantiate !== "function"
|
||||
) {
|
||||
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.",
|
||||
);
|
||||
@@ -61,29 +58,101 @@
|
||||
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;
|
||||
};
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
let len = str.length;
|
||||
let ptr = malloc(len, 1) >>> 0;
|
||||
const mem = getMemory();
|
||||
let offset = 0;
|
||||
|
||||
for (; offset < len; offset++) {
|
||||
const code = str.charCodeAt(offset);
|
||||
if (code > 127) break;
|
||||
mem[ptr + offset] = code;
|
||||
}
|
||||
|
||||
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 (fb) return;
|
||||
if (solve_pow_function === null) {
|
||||
console.warn("[cap worker] no wasm module provided, falling back to JS solver.");
|
||||
return solveFallback({ salt, target });
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
Vendored
-25
@@ -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.
|
||||
@@ -388,8 +368,3 @@ 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",
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user