widget(0.1.36): better widget ui
This commit is contained in:
+5
-1
@@ -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.
|
||||
|
||||
@@ -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=="],
|
||||
|
||||
+44
-22
@@ -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);
|
||||
|
||||
@@ -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=="],
|
||||
|
||||
+86
-69
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
],
|
||||
|
||||
+76
-59
@@ -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/`);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
+622
-578
File diff suppressed because it is too large
Load Diff
+164
-95
@@ -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,
|
||||
});
|
||||
};
|
||||
})();
|
||||
|
||||
Vendored
+1
-26
@@ -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",
|
||||
);
|
||||
);
|
||||
Reference in New Issue
Block a user