@tempoxyz/patron 0.0.19 → 0.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/bin.js +3 -3
- package/dist/chunks/{-I33RKF7A.js → -NGLRKGBT.js} +94 -22
- package/dist/chunks/{chunk-CV2WYKM7.js → chunk-HEQBEBKL.js} +14 -1
- package/dist/chunks/{chunk-WG4BTHH7.js → chunk-UFBFF3R6.js} +245 -15
- package/dist/chunks/{hook-6DRXW2XN.js → hook-IWRRBFKG.js} +1 -1
- package/dist/chunks/{hook-process-XBV2NU4E.js → hook-process-FNSWFVFP.js} +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -50,7 +50,9 @@ and the site's domain through an Oblivious HTTP relay (RFC 9458): the relay sees
|
|
|
50
50
|
not the content; the gateway sees the content but not your IP.
|
|
51
51
|
|
|
52
52
|
Local state lives in `~/.patron`: settings, seals encrypted with AES-256-GCM under a key
|
|
53
|
-
file readable only by you,
|
|
53
|
+
file readable only by you, this month's per-site counts, which never leave the machine, and
|
|
54
|
+
a copy of the CLI in `~/.patron/cli` that agent hooks start with node, so a read never waits
|
|
55
|
+
on npx. Running `npx @tempoxyz/patron` updates the copy.
|
|
54
56
|
|
|
55
57
|
## Budget
|
|
56
58
|
|
package/dist/bin.js
CHANGED
|
@@ -4,14 +4,14 @@ const require = __patronCreateRequire(import.meta.url)
|
|
|
4
4
|
|
|
5
5
|
// src/bin.ts
|
|
6
6
|
if (process.argv[2] === "hook") {
|
|
7
|
-
const { runHookProcess } = await import("./chunks/hook-process-
|
|
7
|
+
const { runHookProcess } = await import("./chunks/hook-process-FNSWFVFP.js");
|
|
8
8
|
await runHookProcess().catch(() => void 0);
|
|
9
9
|
process.exit(0);
|
|
10
10
|
} else if (process.argv[2] === "pay") {
|
|
11
|
-
const { runPayProcess } = await import("./chunks/hook-process-
|
|
11
|
+
const { runPayProcess } = await import("./chunks/hook-process-FNSWFVFP.js");
|
|
12
12
|
await runPayProcess().catch(() => void 0);
|
|
13
13
|
process.exit(0);
|
|
14
14
|
} else {
|
|
15
|
-
const { run } = await import("./chunks/-
|
|
15
|
+
const { run } = await import("./chunks/-NGLRKGBT.js");
|
|
16
16
|
process.exitCode = await run(process.argv.slice(2));
|
|
17
17
|
}
|
|
@@ -28,10 +28,10 @@ import {
|
|
|
28
28
|
withPatronStatus,
|
|
29
29
|
withoutPatronHandlers,
|
|
30
30
|
writeJsonObject
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-UFBFF3R6.js";
|
|
32
32
|
import {
|
|
33
33
|
startRefill
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-HEQBEBKL.js";
|
|
35
35
|
import {
|
|
36
36
|
DEFAULT_MONTHLY_BUDGET_USD,
|
|
37
37
|
MAX_TOKENS_PER_PAGE,
|
|
@@ -62,13 +62,14 @@ import "./chunk-GTMLTZRN.js";
|
|
|
62
62
|
|
|
63
63
|
// src/index.ts
|
|
64
64
|
import { readFileSync } from "node:fs";
|
|
65
|
-
import { rm as
|
|
66
|
-
import { homedir } from "node:os";
|
|
65
|
+
import { rm as rm4 } from "node:fs/promises";
|
|
66
|
+
import { homedir as homedir2 } from "node:os";
|
|
67
67
|
|
|
68
68
|
// src/agents.ts
|
|
69
69
|
import { constants } from "node:fs";
|
|
70
|
-
import { access, realpath } from "node:fs/promises";
|
|
71
|
-
import {
|
|
70
|
+
import { access as access2, realpath as realpath2 } from "node:fs/promises";
|
|
71
|
+
import { homedir } from "node:os";
|
|
72
|
+
import { delimiter, join as join5 } from "node:path";
|
|
72
73
|
|
|
73
74
|
// src/amp.ts
|
|
74
75
|
import { mkdir, readFile, rm } from "node:fs/promises";
|
|
@@ -322,6 +323,66 @@ function parse(text) {
|
|
|
322
323
|
}
|
|
323
324
|
}
|
|
324
325
|
|
|
326
|
+
// src/stable-install.ts
|
|
327
|
+
import {
|
|
328
|
+
access,
|
|
329
|
+
cp,
|
|
330
|
+
mkdir as mkdir2,
|
|
331
|
+
readdir,
|
|
332
|
+
readFile as readFile3,
|
|
333
|
+
readlink,
|
|
334
|
+
realpath,
|
|
335
|
+
rename,
|
|
336
|
+
rm as rm3,
|
|
337
|
+
symlink
|
|
338
|
+
} from "node:fs/promises";
|
|
339
|
+
import { basename, dirname as dirname3, join as join4 } from "node:path";
|
|
340
|
+
function stableBin(home) {
|
|
341
|
+
return join4(home, "cli", "current", "dist", "bin.js");
|
|
342
|
+
}
|
|
343
|
+
async function installStableCli(home, script = process.argv[1]) {
|
|
344
|
+
const resolved = script ? await realpath(script).catch(() => void 0) : void 0;
|
|
345
|
+
if (!resolved || !/[/\\]_npx[/\\]/.test(resolved) || basename(resolved) !== "bin.js")
|
|
346
|
+
return void 0;
|
|
347
|
+
const packageDir = dirname3(dirname3(resolved));
|
|
348
|
+
const { version } = JSON.parse(await readFile3(join4(packageDir, "package.json"), "utf8"));
|
|
349
|
+
if (typeof version !== "string" || !/^[\w.+-]+$/.test(version)) return void 0;
|
|
350
|
+
const root = join4(home, "cli");
|
|
351
|
+
const target = join4(root, version);
|
|
352
|
+
await mkdir2(root, { recursive: true, mode: 448 });
|
|
353
|
+
if (!await isFile(join4(target, "dist", "bin.js"))) {
|
|
354
|
+
const staging = `${target}.${process.pid}.tmp`;
|
|
355
|
+
await rm3(staging, { force: true, recursive: true });
|
|
356
|
+
await cp(join4(packageDir, "dist"), join4(staging, "dist"), { recursive: true });
|
|
357
|
+
await cp(join4(packageDir, "package.json"), join4(staging, "package.json"));
|
|
358
|
+
await rm3(target, { force: true, recursive: true });
|
|
359
|
+
await rename(staging, target);
|
|
360
|
+
}
|
|
361
|
+
const current = join4(root, "current");
|
|
362
|
+
const linked = await readlink(current).catch(() => void 0);
|
|
363
|
+
const previous = linked ? basename(linked) : void 0;
|
|
364
|
+
if (previous !== version) {
|
|
365
|
+
const link = `${current}.${process.pid}.tmp`;
|
|
366
|
+
await rm3(link, { force: true });
|
|
367
|
+
await symlink(process.platform === "win32" ? target : version, link, "junction");
|
|
368
|
+
await rename(link, current).catch(async () => {
|
|
369
|
+
await rm3(current, { force: true, recursive: true });
|
|
370
|
+
await rename(link, current);
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
for (const entry of await readdir(root)) {
|
|
374
|
+
if (entry === "current" || entry === version || entry === previous) continue;
|
|
375
|
+
await rm3(join4(root, entry), { force: true, recursive: true });
|
|
376
|
+
}
|
|
377
|
+
return stableBin(home);
|
|
378
|
+
}
|
|
379
|
+
async function isFile(path) {
|
|
380
|
+
return access(path).then(
|
|
381
|
+
() => true,
|
|
382
|
+
() => false
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
|
|
325
386
|
// src/agents.ts
|
|
326
387
|
var AGENT_LABELS = {
|
|
327
388
|
amp: "Amp",
|
|
@@ -332,7 +393,7 @@ var AGENT_LABELS = {
|
|
|
332
393
|
var ADAPTERS = {
|
|
333
394
|
amp: {
|
|
334
395
|
files: ({ env, home }) => [ampPluginPath(env, home)],
|
|
335
|
-
detect: async ({ env, home }) => await exists(
|
|
396
|
+
detect: async ({ env, home }) => await exists(join5(env.XDG_CONFIG_HOME || join5(home, ".config"), "amp")) || await onPath(["amp"], env.PATH ?? ""),
|
|
336
397
|
install: async (command, { env, home }) => ({
|
|
337
398
|
state: await installAmpPlugin(ampPluginPath(env, home), command)
|
|
338
399
|
}),
|
|
@@ -357,7 +418,7 @@ var ADAPTERS = {
|
|
|
357
418
|
},
|
|
358
419
|
cursor: {
|
|
359
420
|
files: ({ home }) => [cursorHooksPath(home)],
|
|
360
|
-
detect: async ({ env, home }) => await exists(
|
|
421
|
+
detect: async ({ env, home }) => await exists(join5(home, ".cursor")) || await onPath(["cursor-agent", "cursor"], env.PATH ?? ""),
|
|
361
422
|
install: async (command, { home }) => ({
|
|
362
423
|
state: await installCursorHook(cursorHooksPath(home), command)
|
|
363
424
|
}),
|
|
@@ -365,10 +426,10 @@ var ADAPTERS = {
|
|
|
365
426
|
}
|
|
366
427
|
};
|
|
367
428
|
function claudeDirectory({ env, home }) {
|
|
368
|
-
return env.CLAUDE_CONFIG_DIR ||
|
|
429
|
+
return env.CLAUDE_CONFIG_DIR || join5(home, ".claude");
|
|
369
430
|
}
|
|
370
431
|
function claudeSettingsPath(environment) {
|
|
371
|
-
return
|
|
432
|
+
return join5(claudeDirectory(environment), "settings.json");
|
|
372
433
|
}
|
|
373
434
|
async function detectAgents(environment) {
|
|
374
435
|
const found = await Promise.all(
|
|
@@ -421,7 +482,7 @@ async function removeAgents(environment) {
|
|
|
421
482
|
);
|
|
422
483
|
}
|
|
423
484
|
function originalsStore({ env, home }) {
|
|
424
|
-
return originalsPath(env.PATRON_HOME ||
|
|
485
|
+
return originalsPath(env.PATRON_HOME || join5(home, ".patron"));
|
|
425
486
|
}
|
|
426
487
|
function failure(agent, error) {
|
|
427
488
|
return {
|
|
@@ -431,18 +492,20 @@ function failure(agent, error) {
|
|
|
431
492
|
state: "failed"
|
|
432
493
|
};
|
|
433
494
|
}
|
|
434
|
-
async function hookCommand(env = process.env, script = process.argv[1], node = process.execPath) {
|
|
495
|
+
async function hookCommand(env = process.env, script = process.argv[1], node = process.execPath, patronHome = env.PATRON_HOME || join5(homedir(), ".patron")) {
|
|
435
496
|
if (env.PATRON_HOOK_COMMAND) return env.PATRON_HOOK_COMMAND;
|
|
436
|
-
const resolved = script ? await
|
|
497
|
+
const resolved = script ? await realpath2(script).catch(() => void 0) : void 0;
|
|
437
498
|
if (resolved && /[/\\]bin\.js$/.test(resolved) && !/[/\\]_npx[/\\]/.test(resolved))
|
|
438
499
|
return `${quote(node)} ${quote(resolved)} hook`;
|
|
500
|
+
if (await exists(stableBin(patronHome)))
|
|
501
|
+
return `${quote(node)} ${quote(stableBin(patronHome))} hook`;
|
|
439
502
|
return "npx -y @tempoxyz/patron hook";
|
|
440
503
|
}
|
|
441
504
|
function quote(value) {
|
|
442
505
|
return /^[\w./:@-]+$/.test(value) ? value : `'${value.replaceAll("'", "'\\''")}'`;
|
|
443
506
|
}
|
|
444
507
|
async function exists(path) {
|
|
445
|
-
return
|
|
508
|
+
return access2(path).then(
|
|
446
509
|
() => true,
|
|
447
510
|
() => false
|
|
448
511
|
);
|
|
@@ -451,7 +514,7 @@ async function onPath(commands, path) {
|
|
|
451
514
|
for (const directory of path.split(delimiter)) {
|
|
452
515
|
if (!directory) continue;
|
|
453
516
|
for (const command of commands) {
|
|
454
|
-
const found = await
|
|
517
|
+
const found = await access2(join5(directory, command), constants.X_OK).then(
|
|
455
518
|
() => true,
|
|
456
519
|
() => false
|
|
457
520
|
);
|
|
@@ -744,7 +807,7 @@ function defaults() {
|
|
|
744
807
|
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
745
808
|
const color = supportsColor(process.stdout);
|
|
746
809
|
return {
|
|
747
|
-
agents: { env: process.env, home:
|
|
810
|
+
agents: { env: process.env, home: homedir2() },
|
|
748
811
|
color,
|
|
749
812
|
fetch: globalThis.fetch,
|
|
750
813
|
interactive,
|
|
@@ -848,6 +911,18 @@ async function main(deps) {
|
|
|
848
911
|
await status(deps, deps.interactive);
|
|
849
912
|
}
|
|
850
913
|
async function syncAgents(deps, config) {
|
|
914
|
+
await installStableCli(deps.settings.home).catch(() => void 0);
|
|
915
|
+
const command = await hookCommand(deps.agents.env);
|
|
916
|
+
const moved = (await installAgents(config.agents, command, deps.agents)).filter((result) => result.state === "installed").map((result) => result.agent);
|
|
917
|
+
if (moved.length > 0) {
|
|
918
|
+
say(
|
|
919
|
+
deps,
|
|
920
|
+
`Patron now starts with node for ${moved.map((a) => AGENT_LABELS[a]).join(", ")}.`
|
|
921
|
+
);
|
|
922
|
+
if (moved.includes("codex"))
|
|
923
|
+
say(deps, " Codex: trust the hook again in /hooks when it asks.");
|
|
924
|
+
say(deps);
|
|
925
|
+
}
|
|
851
926
|
const upgraded = await upgradeAgents(config.agents, deps.agents);
|
|
852
927
|
if (upgraded.length > 0) {
|
|
853
928
|
const names = upgraded.map((agent) => AGENT_LABELS[agent]).join(", ");
|
|
@@ -860,11 +935,7 @@ async function syncAgents(deps, config) {
|
|
|
860
935
|
(agent) => !config.agents.includes(agent)
|
|
861
936
|
);
|
|
862
937
|
if (added.length === 0) return;
|
|
863
|
-
const results = await installAgents(
|
|
864
|
-
added,
|
|
865
|
-
await hookCommand(deps.agents.env),
|
|
866
|
-
deps.agents
|
|
867
|
-
);
|
|
938
|
+
const results = await installAgents(added, command, deps.agents);
|
|
868
939
|
for (const line of formatAgentResults(results, deps.color)) say(deps, line);
|
|
869
940
|
say(deps);
|
|
870
941
|
const installed = results.filter((result) => result.state !== "failed").map((result) => result.agent);
|
|
@@ -910,6 +981,7 @@ async function setup(deps) {
|
|
|
910
981
|
const bought = await buyWithinBudget(settings, config, STARTER_TOKENS, deps.openWallet);
|
|
911
982
|
done(deps, `${bought.toLocaleString("en-US")} seals ready`);
|
|
912
983
|
deps.startRefill();
|
|
984
|
+
await installStableCli(settings.home).catch(() => void 0);
|
|
913
985
|
const agents = await detectAgents(deps.agents);
|
|
914
986
|
if (agents.length === 0) {
|
|
915
987
|
say(deps);
|
|
@@ -1147,7 +1219,7 @@ async function uninstall(deps) {
|
|
|
1147
1219
|
}
|
|
1148
1220
|
}
|
|
1149
1221
|
if (purge) {
|
|
1150
|
-
await
|
|
1222
|
+
await rm4(deps.settings.home, { force: true, recursive: true });
|
|
1151
1223
|
done(deps, "Local data deleted.");
|
|
1152
1224
|
} else
|
|
1153
1225
|
say(
|
|
@@ -3,10 +3,12 @@ const require = __patronCreateRequire(import.meta.url)
|
|
|
3
3
|
|
|
4
4
|
// src/refill-process.ts
|
|
5
5
|
import { spawn } from "node:child_process";
|
|
6
|
+
import { createRequire } from "node:module";
|
|
6
7
|
function startRefill(script = process.argv[1]) {
|
|
7
8
|
try {
|
|
8
9
|
if (!script) return;
|
|
9
|
-
const
|
|
10
|
+
const [command, args] = refillCommand(script);
|
|
11
|
+
const child = spawn(command, args, {
|
|
10
12
|
detached: true,
|
|
11
13
|
env: process.env,
|
|
12
14
|
stdio: "ignore"
|
|
@@ -16,6 +18,17 @@ function startRefill(script = process.argv[1]) {
|
|
|
16
18
|
} catch {
|
|
17
19
|
}
|
|
18
20
|
}
|
|
21
|
+
function refillCommand(script) {
|
|
22
|
+
try {
|
|
23
|
+
createRequire(script).resolve("mppx");
|
|
24
|
+
return [process.execPath, [...process.execArgv, script, "refill"]];
|
|
25
|
+
} catch {
|
|
26
|
+
return [
|
|
27
|
+
process.platform === "win32" ? "npx.cmd" : "npx",
|
|
28
|
+
["-y", "@tempoxyz/patron", "refill"]
|
|
29
|
+
];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
19
32
|
function startPayment(payload, script = process.argv[1]) {
|
|
20
33
|
return new Promise((resolve) => {
|
|
21
34
|
try {
|
|
@@ -34215,9 +34215,9 @@ var PARTIALLY_BLIND_RSA_TOKEN_TYPE = {
|
|
|
34215
34215
|
|
|
34216
34216
|
// ../../node_modules/.pnpm/@cloudflare+privacypass-ts@0.9.0/node_modules/@cloudflare/privacypass-ts/lib/src/pub_verif_token.js
|
|
34217
34217
|
var BlindRSAMode;
|
|
34218
|
-
(function(
|
|
34219
|
-
|
|
34220
|
-
|
|
34218
|
+
(function(BlindRSAMode2) {
|
|
34219
|
+
BlindRSAMode2[BlindRSAMode2["PSSZero"] = 0] = "PSSZero";
|
|
34220
|
+
BlindRSAMode2[BlindRSAMode2["PSS"] = 48] = "PSS";
|
|
34221
34221
|
})(BlindRSAMode || (BlindRSAMode = {}));
|
|
34222
34222
|
var PartiallyBlindRSAMode = BlindRSAMode;
|
|
34223
34223
|
var BLINDRSA_EXTRA_PARAMS = {
|
|
@@ -34538,29 +34538,259 @@ var MediaType2;
|
|
|
34538
34538
|
MediaType3["GENERIC_BATCHED_TOKEN_RESPONSE"] = "application/private-token-generic-batch-response";
|
|
34539
34539
|
})(MediaType2 || (MediaType2 = {}));
|
|
34540
34540
|
|
|
34541
|
+
// ../client/src/blind-rsa.ts
|
|
34542
|
+
var HASH = "SHA-384";
|
|
34543
|
+
var HASH_LENGTH = 48;
|
|
34544
|
+
var SALT_LENGTH = 48;
|
|
34545
|
+
var MAX_BLIND_ATTEMPTS = 128;
|
|
34546
|
+
async function importBlindRsaKey(cryptoKey) {
|
|
34547
|
+
const algorithm = cryptoKey.algorithm;
|
|
34548
|
+
if (cryptoKey.type !== "public" || algorithm.name !== "RSA-PSS")
|
|
34549
|
+
throw new Error("key is not an RSA-PSS public key");
|
|
34550
|
+
if (algorithm.hash.name !== HASH) throw new Error(`key hash is not ${HASH}`);
|
|
34551
|
+
const jwk = await crypto.subtle.exportKey("jwk", cryptoKey);
|
|
34552
|
+
if (!jwk.n || !jwk.e) throw new Error("key has invalid parameters");
|
|
34553
|
+
const n = bytesToInt(fromBase64UrlBytes(jwk.n));
|
|
34554
|
+
const e = bytesToInt(fromBase64UrlBytes(jwk.e));
|
|
34555
|
+
const modulusBits = n.toString(2).length;
|
|
34556
|
+
if (modulusBits !== algorithm.modulusLength)
|
|
34557
|
+
throw new Error("key has invalid parameters");
|
|
34558
|
+
return { cryptoKey, n, e, modulusBits, modulusBytes: Math.ceil(modulusBits / 8) };
|
|
34559
|
+
}
|
|
34560
|
+
async function blind(key, messages) {
|
|
34561
|
+
const encoded = await Promise.all(
|
|
34562
|
+
messages.map(
|
|
34563
|
+
(msg) => emsaPssEncode(
|
|
34564
|
+
msg,
|
|
34565
|
+
key.modulusBits - 1,
|
|
34566
|
+
crypto.getRandomValues(new Uint8Array(SALT_LENGTH))
|
|
34567
|
+
)
|
|
34568
|
+
)
|
|
34569
|
+
);
|
|
34570
|
+
return blindEncoded(key, encoded, randomBlindingFactors(key, messages.length));
|
|
34571
|
+
}
|
|
34572
|
+
function blindEncoded(key, encoded, factors) {
|
|
34573
|
+
const { n } = key;
|
|
34574
|
+
if (encoded.length !== factors.length)
|
|
34575
|
+
throw new Error("one blinding factor per message");
|
|
34576
|
+
const messages = encoded.map(bytesToInt);
|
|
34577
|
+
let product = 1n;
|
|
34578
|
+
for (const m of messages) {
|
|
34579
|
+
if (m >= n) throw new Error("invalid input");
|
|
34580
|
+
product = product * m % n;
|
|
34581
|
+
}
|
|
34582
|
+
if (gcd(product, n) !== 1n) throw new Error("invalid input");
|
|
34583
|
+
return messages.map((m, index) => {
|
|
34584
|
+
const factor = factors[index];
|
|
34585
|
+
const z2 = m * modPow(factor.r, key.e, n) % n;
|
|
34586
|
+
return { blindedMsg: intToBytes(z2, key.modulusBytes), inv: factor.inv };
|
|
34587
|
+
});
|
|
34588
|
+
}
|
|
34589
|
+
async function finalize2(key, msg, blindSig, inv) {
|
|
34590
|
+
if (blindSig.length !== key.modulusBytes) throw new Error("unexpected input size");
|
|
34591
|
+
const z2 = bytesToInt(blindSig);
|
|
34592
|
+
if (z2 >= key.n) throw new Error("invalid signature");
|
|
34593
|
+
const sig = intToBytes(z2 * inv % key.n, key.modulusBytes);
|
|
34594
|
+
const valid = await crypto.subtle.verify(
|
|
34595
|
+
{ name: "RSA-PSS", saltLength: SALT_LENGTH },
|
|
34596
|
+
key.cryptoKey,
|
|
34597
|
+
sig,
|
|
34598
|
+
msg.slice()
|
|
34599
|
+
);
|
|
34600
|
+
if (!valid) throw new Error("invalid signature");
|
|
34601
|
+
return sig;
|
|
34602
|
+
}
|
|
34603
|
+
async function emsaPssEncode(msg, emBits, salt) {
|
|
34604
|
+
const emLength = Math.ceil(emBits / 8);
|
|
34605
|
+
if (emLength < HASH_LENGTH + salt.length + 2) throw new Error("encoding error");
|
|
34606
|
+
const mHash = await digest(msg);
|
|
34607
|
+
const mPrime = new Uint8Array(8 + HASH_LENGTH + salt.length);
|
|
34608
|
+
mPrime.set(mHash, 8);
|
|
34609
|
+
mPrime.set(salt, 8 + HASH_LENGTH);
|
|
34610
|
+
const h = await digest(mPrime);
|
|
34611
|
+
const dbLength = emLength - HASH_LENGTH - 1;
|
|
34612
|
+
const mask = await mgf12(h, dbLength);
|
|
34613
|
+
const em = new Uint8Array(emLength);
|
|
34614
|
+
em[dbLength - salt.length - 1] = 1;
|
|
34615
|
+
em.set(salt, dbLength - salt.length);
|
|
34616
|
+
for (let index = 0; index < dbLength; index++)
|
|
34617
|
+
em[index] = (em[index] ?? 0) ^ (mask[index] ?? 0);
|
|
34618
|
+
em[0] = (em[0] ?? 0) & 255 >> 8 * emLength - emBits;
|
|
34619
|
+
em.set(h, dbLength);
|
|
34620
|
+
em[emLength - 1] = 188;
|
|
34621
|
+
return em;
|
|
34622
|
+
}
|
|
34623
|
+
function inverseMod2(a, n) {
|
|
34624
|
+
let oldR = a % n;
|
|
34625
|
+
let r = n;
|
|
34626
|
+
let oldS = 1n;
|
|
34627
|
+
let s = 0n;
|
|
34628
|
+
while (r !== 0n) {
|
|
34629
|
+
const quotient = oldR / r;
|
|
34630
|
+
const nextR = oldR - quotient * r;
|
|
34631
|
+
oldR = r;
|
|
34632
|
+
r = nextR;
|
|
34633
|
+
const nextS = oldS - quotient * s;
|
|
34634
|
+
oldS = s;
|
|
34635
|
+
s = nextS;
|
|
34636
|
+
}
|
|
34637
|
+
if (oldR !== 1n) return void 0;
|
|
34638
|
+
return oldS < 0n ? oldS + n : oldS;
|
|
34639
|
+
}
|
|
34640
|
+
function randomBlindingFactors(key, count) {
|
|
34641
|
+
const { n } = key;
|
|
34642
|
+
for (let attempt = 0; attempt < MAX_BLIND_ATTEMPTS; attempt++) {
|
|
34643
|
+
const factors = Array.from({ length: count }, () => randomBelow(key));
|
|
34644
|
+
const prefixes = [];
|
|
34645
|
+
let product = 1n;
|
|
34646
|
+
for (const r of factors) {
|
|
34647
|
+
product = product * r % n;
|
|
34648
|
+
prefixes.push(product);
|
|
34649
|
+
}
|
|
34650
|
+
let inverse = inverseMod2(product, n);
|
|
34651
|
+
if (inverse === void 0) continue;
|
|
34652
|
+
const inverses = new Array(count);
|
|
34653
|
+
for (let index = count - 1; index >= 0; index--) {
|
|
34654
|
+
const r = factors[index];
|
|
34655
|
+
inverses[index] = index === 0 ? inverse : inverse * prefixes[index - 1] % n;
|
|
34656
|
+
inverse = inverse * r % n;
|
|
34657
|
+
}
|
|
34658
|
+
return factors.map((r, index) => ({ r, inv: inverses[index] }));
|
|
34659
|
+
}
|
|
34660
|
+
throw new Error("blinding error: no invertible blinding factor found");
|
|
34661
|
+
}
|
|
34662
|
+
function randomBelow(key) {
|
|
34663
|
+
const bytes = new Uint8Array(key.modulusBytes);
|
|
34664
|
+
const topMask = 255 >> 8 * key.modulusBytes - key.modulusBits;
|
|
34665
|
+
try {
|
|
34666
|
+
for (let attempt = 0; attempt < MAX_BLIND_ATTEMPTS; attempt++) {
|
|
34667
|
+
crypto.getRandomValues(bytes);
|
|
34668
|
+
bytes[0] = (bytes[0] ?? 0) & topMask;
|
|
34669
|
+
const r = bytesToInt(bytes);
|
|
34670
|
+
if (r !== 0n && r < key.n) return r;
|
|
34671
|
+
}
|
|
34672
|
+
} finally {
|
|
34673
|
+
bytes.fill(0);
|
|
34674
|
+
}
|
|
34675
|
+
throw new Error("blinding error: no blinding factor below n found");
|
|
34676
|
+
}
|
|
34677
|
+
function modPow(base, exponent, modulus) {
|
|
34678
|
+
let result = 1n;
|
|
34679
|
+
let square = base % modulus;
|
|
34680
|
+
let remaining = exponent;
|
|
34681
|
+
while (remaining > 0n) {
|
|
34682
|
+
if (remaining & 1n) result = result * square % modulus;
|
|
34683
|
+
remaining >>= 1n;
|
|
34684
|
+
if (remaining > 0n) square = square * square % modulus;
|
|
34685
|
+
}
|
|
34686
|
+
return result;
|
|
34687
|
+
}
|
|
34688
|
+
function gcd(a, b) {
|
|
34689
|
+
let x = a;
|
|
34690
|
+
let y = b;
|
|
34691
|
+
while (y !== 0n) {
|
|
34692
|
+
const next = x % y;
|
|
34693
|
+
x = y;
|
|
34694
|
+
y = next;
|
|
34695
|
+
}
|
|
34696
|
+
return x;
|
|
34697
|
+
}
|
|
34698
|
+
async function mgf12(seed, length2) {
|
|
34699
|
+
const blocks = Math.ceil(length2 / HASH_LENGTH);
|
|
34700
|
+
const hashes = await Promise.all(
|
|
34701
|
+
Array.from({ length: blocks }, (_, counter) => {
|
|
34702
|
+
const input2 = new Uint8Array(seed.length + 4);
|
|
34703
|
+
input2.set(seed);
|
|
34704
|
+
new DataView(input2.buffer).setUint32(seed.length, counter);
|
|
34705
|
+
return digest(input2);
|
|
34706
|
+
})
|
|
34707
|
+
);
|
|
34708
|
+
const mask = new Uint8Array(blocks * HASH_LENGTH);
|
|
34709
|
+
hashes.forEach((hash2, index) => {
|
|
34710
|
+
mask.set(hash2, index * HASH_LENGTH);
|
|
34711
|
+
});
|
|
34712
|
+
return mask.subarray(0, length2);
|
|
34713
|
+
}
|
|
34714
|
+
async function digest(data) {
|
|
34715
|
+
return new Uint8Array(await crypto.subtle.digest(HASH, data.slice()));
|
|
34716
|
+
}
|
|
34717
|
+
var HEX = Array.from({ length: 256 }, (_, byte) => byte.toString(16).padStart(2, "0"));
|
|
34718
|
+
function bytesToInt(bytes) {
|
|
34719
|
+
if (bytes.length === 0) return 0n;
|
|
34720
|
+
let hex3 = "";
|
|
34721
|
+
for (const byte of bytes) hex3 += HEX[byte];
|
|
34722
|
+
return BigInt(`0x${hex3}`);
|
|
34723
|
+
}
|
|
34724
|
+
function intToBytes(value, length2) {
|
|
34725
|
+
const hex3 = value.toString(16);
|
|
34726
|
+
if (value < 0n || hex3.length > length2 * 2) throw new Error("integer too large");
|
|
34727
|
+
const padded = hex3.padStart(length2 * 2, "0");
|
|
34728
|
+
const bytes = new Uint8Array(length2);
|
|
34729
|
+
for (let index = 0; index < length2; index++)
|
|
34730
|
+
bytes[index] = Number.parseInt(padded.slice(index * 2, index * 2 + 2), 16);
|
|
34731
|
+
return bytes;
|
|
34732
|
+
}
|
|
34733
|
+
function fromBase64UrlBytes(value) {
|
|
34734
|
+
const base643 = value.replaceAll("-", "+").replaceAll("_", "/");
|
|
34735
|
+
const binary = atob(base643 + "=".repeat((4 - base643.length % 4) % 4));
|
|
34736
|
+
return Uint8Array.from(binary, (char) => char.charCodeAt(0));
|
|
34737
|
+
}
|
|
34738
|
+
|
|
34541
34739
|
// ../client/src/privacy-pass.ts
|
|
34542
|
-
var {
|
|
34740
|
+
var { BLIND_RSA: BLIND_RSA2, TokenRequest: TokenRequest3, TokenResponse: TokenResponse3, convertRSASSAPSSToEnc: convertRSASSAPSSToEnc2 } = pub_verif_token_exports;
|
|
34543
34741
|
function tokenChallenge() {
|
|
34544
34742
|
return new TokenChallenge(TOKEN_TYPE, ISSUER_NAME, new Uint8Array(0));
|
|
34545
34743
|
}
|
|
34546
34744
|
async function createTokenRequests(publicKey, count) {
|
|
34745
|
+
if (!(count > 0)) return [];
|
|
34547
34746
|
const issuerKey = fromBase64Url(publicKey);
|
|
34548
|
-
const
|
|
34549
|
-
|
|
34550
|
-
|
|
34551
|
-
|
|
34552
|
-
|
|
34553
|
-
|
|
34747
|
+
const cryptoKey = await crypto.subtle.importKey(
|
|
34748
|
+
"spki",
|
|
34749
|
+
convertRSASSAPSSToEnc2(issuerKey).slice(),
|
|
34750
|
+
BLIND_RSA2.rsaParams,
|
|
34751
|
+
true,
|
|
34752
|
+
["verify"]
|
|
34753
|
+
);
|
|
34754
|
+
const key = await importBlindRsaKey(cryptoKey);
|
|
34755
|
+
if (key.modulusBytes !== BLIND_RSA2.Nk) throw new Error("issuer key is not RSA-2048");
|
|
34756
|
+
const [tokenKeyId, challengeDigest] = await Promise.all([
|
|
34757
|
+
sha256(issuerKey),
|
|
34758
|
+
sha256(tokenChallenge().serialize())
|
|
34759
|
+
]);
|
|
34760
|
+
const truncatedTokenKeyId = tokenKeyId[tokenKeyId.length - 1] ?? 0;
|
|
34761
|
+
const inputs = Array.from({ length: Math.ceil(count) }, () => {
|
|
34762
|
+
const nonce = crypto.getRandomValues(new Uint8Array(32));
|
|
34763
|
+
return new AuthenticatorInput(
|
|
34764
|
+
BLIND_RSA2,
|
|
34765
|
+
BLIND_RSA2.value,
|
|
34766
|
+
nonce,
|
|
34767
|
+
challengeDigest,
|
|
34768
|
+
tokenKeyId
|
|
34769
|
+
);
|
|
34770
|
+
});
|
|
34771
|
+
const tokenInputs = inputs.map((input2) => input2.serialize());
|
|
34772
|
+
const blinded = await blind(key, tokenInputs);
|
|
34773
|
+
const pending = inputs.map((authInput, index) => {
|
|
34774
|
+
const tokenInput = tokenInputs[index];
|
|
34775
|
+
const { blindedMsg, inv: blindInv } = blinded[index];
|
|
34776
|
+
let inv = blindInv;
|
|
34777
|
+
const request = new TokenRequest3(truncatedTokenKeyId, blindedMsg, BLIND_RSA2);
|
|
34778
|
+
return {
|
|
34554
34779
|
request: toBase64Url(request.serialize()),
|
|
34555
34780
|
async finalize(signature) {
|
|
34556
|
-
|
|
34557
|
-
const
|
|
34558
|
-
|
|
34781
|
+
if (inv === void 0) throw new Error("token was already finalized");
|
|
34782
|
+
const response = TokenResponse3.deserialize(fromBase64Url(signature));
|
|
34783
|
+
const authenticator = await finalize2(key, tokenInput, response.blindSig, inv);
|
|
34784
|
+
inv = void 0;
|
|
34785
|
+
return toBase64Url(new Token(BLIND_RSA2, authInput, authenticator).serialize());
|
|
34559
34786
|
}
|
|
34560
|
-
}
|
|
34561
|
-
}
|
|
34787
|
+
};
|
|
34788
|
+
});
|
|
34562
34789
|
return pending;
|
|
34563
34790
|
}
|
|
34791
|
+
async function sha256(data) {
|
|
34792
|
+
return new Uint8Array(await crypto.subtle.digest("SHA-256", data.slice()));
|
|
34793
|
+
}
|
|
34564
34794
|
|
|
34565
34795
|
// ../client/src/index.ts
|
|
34566
34796
|
async function getIssuer(gatewayUrl, fetchFn = fetch) {
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
import {
|
|
11
11
|
startPayment,
|
|
12
12
|
startRefill
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-HEQBEBKL.js";
|
|
14
14
|
import {
|
|
15
15
|
resolveSettings
|
|
16
16
|
} from "./chunk-CF4LJZLC.js";
|
|
@@ -25,7 +25,7 @@ async function runHookProcess(argument = process.argv[3]) {
|
|
|
25
25
|
if (isCursorPayload(payload)) process.stdout.write("{}\n");
|
|
26
26
|
if (!turnEnd(payload) && hookDomains(payload).length === 0) return;
|
|
27
27
|
if (await startPayment(raw)) return;
|
|
28
|
-
const { runHook } = await import("./hook-
|
|
28
|
+
const { runHook } = await import("./hook-IWRRBFKG.js");
|
|
29
29
|
await runHook({
|
|
30
30
|
readInput: async () => raw,
|
|
31
31
|
settings: resolveSettings(),
|
|
@@ -33,7 +33,7 @@ async function runHookProcess(argument = process.argv[3]) {
|
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
35
|
async function runPayProcess() {
|
|
36
|
-
const { PAY_TIMEOUT_MS, runHook } = await import("./hook-
|
|
36
|
+
const { PAY_TIMEOUT_MS, runHook } = await import("./hook-IWRRBFKG.js");
|
|
37
37
|
setTimeout(() => process.exit(0), PAY_TIMEOUT_MS + 1e3).unref();
|
|
38
38
|
const raw = await readStdin(HOOK_TIMEOUT_MS);
|
|
39
39
|
await runHook(
|