@genkaku/protocol 0.1.17 → 0.1.18

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/dist/bridge.js CHANGED
@@ -4,7 +4,7 @@
4
4
  // escrow on Base Sepolia. No provider wire code leaks into dsh.
5
5
  import { appendFileSync } from 'node:fs';
6
6
  import { createServer } from 'node:http';
7
- import { applyLoopbackCors } from "./cors.js";
7
+ import { applyPanelCors } from "./cors.js";
8
8
  import { openEscrow, publicClientFor, readWorker, refundSession, settleSession, signReceiptPayload, walletAddress, walletClientFor, } from "./chain.js";
9
9
  import { dialWorkerAny, fetchOffers, requestSettleCosign } from "./dial.js";
10
10
  import { dedupeOffers, toWire } from "./offer.js";
@@ -533,7 +533,7 @@ export async function startOpenAiBridge(opts) {
533
533
  void (async () => {
534
534
  try {
535
535
  const path = (req.url ?? '/').split('?')[0] ?? '/';
536
- if (!applyLoopbackCors(req, res)) {
536
+ if (!applyPanelCors(req, res)) {
537
537
  res.writeHead(403, { 'content-type': 'application/json' });
538
538
  res.end(JSON.stringify({ error: { message: 'origin not allowed' } }));
539
539
  return;
package/dist/cors.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { IncomingMessage, ServerResponse } from 'node:http';
2
2
  /**
3
- * Apply CORS headers when the request comes from a loopback origin.
4
- * @returns false when a browser origin outside loopback tried to call us.
3
+ * Apply CORS headers when the request comes from a host allowed to show a panel.
4
+ * @returns false when a browser origin outside that set tried to call us.
5
5
  */
6
- export declare function applyLoopbackCors(req: IncomingMessage, res: ServerResponse): boolean;
6
+ export declare function applyPanelCors(req: IncomingMessage, res: ServerResponse): boolean;
7
7
  //# sourceMappingURL=cors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../src/cors.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAIhE;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAepF"}
1
+ {"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../src/cors.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAOhE;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAejF"}
package/dist/cors.js CHANGED
@@ -1,21 +1,32 @@
1
- // GENKAKU: CORS for the loopback control planes.
1
+ // GENKAKU: CORS for the local control planes.
2
2
  //
3
3
  // The bridge and the worker status server answer on 127.0.0.1 and used to send
4
4
  // `access-control-allow-origin: *`. Any website the user visited could then
5
- // read wallet state and, once wallet endpoints existed, key material. Only a
6
- // loopback Origin (the DSH web app) may read these responses.
5
+ // read wallet state and, once wallet endpoints existed, key material. Now only
6
+ // the two hosts that actually render a panel may read these responses:
7
+ //
8
+ // - the DSH web app served from loopback (`dsh web` in a browser), and
9
+ // - the official DSH desktop app, whose renderer runs on `dsh-app://app`.
10
+ // Chromium sends that origin on every cross-origin fetch, and the app's own
11
+ // web route authenticates with the same string.
12
+ //
13
+ // `null` stays rejected. A sandboxed iframe on any website carries that origin,
14
+ // and file:// pages do too, so allowing it would hand every page the key
15
+ // material this gate exists to protect.
7
16
  const LOOPBACK = /^https?:\/\/(127\.0\.0\.1|localhost|\[::1\])(:\d+)?$/;
17
+ /** Origin of the official DSH desktop renderer (Electron custom scheme). */
18
+ const DESKTOP_APP = 'dsh-app://app';
8
19
  /**
9
- * Apply CORS headers when the request comes from a loopback origin.
10
- * @returns false when a browser origin outside loopback tried to call us.
20
+ * Apply CORS headers when the request comes from a host allowed to show a panel.
21
+ * @returns false when a browser origin outside that set tried to call us.
11
22
  */
12
- export function applyLoopbackCors(req, res) {
23
+ export function applyPanelCors(req, res) {
13
24
  const origin = req.headers.origin;
14
25
  // curl, the HTML dashboard (same-origin navigation) and node clients send no
15
26
  // Origin; they are not subject to the browser's cross-origin rules.
16
27
  if (origin == null)
17
28
  return true;
18
- if (!LOOPBACK.test(origin))
29
+ if (!LOOPBACK.test(origin) && origin !== DESKTOP_APP)
19
30
  return false;
20
31
  res.setHeader('access-control-allow-origin', origin);
21
32
  res.setHeader('vary', 'origin');
package/dist/status.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // GET /genkaku/status (JSON). Snapshot is called per request so the page and
3
3
  // the JSON always reflect the live sidecar, never a boot-time copy.
4
4
  import { createServer } from 'node:http';
5
- import { applyLoopbackCors } from "./cors.js";
5
+ import { applyPanelCors } from "./cors.js";
6
6
  /** Self-contained dashboard; mirrors the user bridge style and polls the JSON. */
7
7
  const DASHBOARD_HTML = `<!doctype html>
8
8
  <html lang="en">
@@ -171,7 +171,7 @@ export async function startStatusServer(port, snapshot, onCatalog, onMode, ollam
171
171
  void (async () => {
172
172
  try {
173
173
  const path = (req.url ?? '/').split('?')[0] ?? '/';
174
- if (!applyLoopbackCors(req, res)) {
174
+ if (!applyPanelCors(req, res)) {
175
175
  res.writeHead(403, { 'content-type': 'application/json' });
176
176
  res.end(JSON.stringify({ error: { message: 'origin not allowed' } }));
177
177
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genkaku/protocol",
3
- "version": "0.1.17",
3
+ "version": "0.1.18",
4
4
  "description": "GenKaKu protocol core: on-chain worker directory, USDC escrow billing, libp2p transport, Ollama lifecycle",
5
5
  "license": "MIT",
6
6
  "type": "module",