craftar 0.36.0 → 0.37.0

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/ui/server.js CHANGED
@@ -1,17 +1,20 @@
1
1
  import { randomBytes, timingSafeEqual } from "node:crypto";
2
2
  import http from "node:http";
3
3
  import { errorText } from "../core/schema-fault.js";
4
- import { PAGE_CSS, PAGE_HTML, PAGE_JS } from "./page.js";
5
- import { route as defaultRoute, routePattern } from "./routes.js";
4
+ import { PAGE_CSS, PAGE_HTML, PAGE_JS, pageCss, pageJs } from "./page.js";
5
+ import { parseWriteBody, route as defaultRoute, routePattern, WRITE_PATTERNS } from "./routes.js";
6
6
  /**
7
- * The loopback server of `craftar ui` (spec 36 §4.5, §7) — the one file under `src/` that imports `node:http`.
7
+ * The loopback server of `craftar ui` (spec 36 §4.5, §7; spec 40 §6.3) — the one file under `src/` that imports `node:http`.
8
8
  * It never prints and never exits: what the terminal must see goes through `opts.onError`.
9
9
  *
10
- * Every request passes the same checks, in this order, and the order is the contract (§7.2):
10
+ * Every request passes the same checks, in this order, and the order is the contract (spec 36 §7.2, spec 40 §6.3):
11
11
  * method → length of the target → `Host` → `Origin` and `Sec-Fetch-Site` → the route (a static one answers
12
- * here; an unknown path is 404) → the run token → the queue of one → `route()`.
12
+ * here; an unknown path is 404; without `allowWrites` a write pattern is 404) → the run token → (for POST)
13
+ * `Content-Type` → the body → the queue of one → `route()`.
13
14
  */
14
15
  export const MAX_TARGET_BYTES = 2048;
16
+ export const MAX_BODY_BYTES = 4096;
17
+ export const MAX_DRAIN_BYTES = 1024 * 1024;
15
18
  export const CSP = "default-src 'none'; script-src 'self'; style-src 'self'; connect-src 'self'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'";
16
19
  /** The names this server answers to. `localhost` is not one: it may resolve elsewhere, and a rebound name could read as it. */
17
20
  const names = (port) => (port === 80 ? ["127.0.0.1", "127.0.0.1:80"] : [`127.0.0.1:${port}`]);
@@ -19,11 +22,14 @@ export const hostAllowed = (header, port) => header !== undefined && names(port)
19
22
  /** Absent is allowed: a browser sends no `Origin` on a navigation or a same-origin GET. `null` is not. */
20
23
  export const originAllowed = (header, port) => header === undefined || names(port).some((n) => header === `http://${n}`);
21
24
  export const siteAllowed = (header) => header === undefined || header === "same-origin" || header === "none";
22
- const STATIC = {
23
- "/": ["text/html; charset=utf-8", PAGE_HTML],
24
- "/app.js": ["text/javascript; charset=utf-8", PAGE_JS],
25
- "/app.css": ["text/css; charset=utf-8", PAGE_CSS],
26
- };
25
+ /** Builds the static routes: one HTML, one JS, one CSS. */
26
+ function staticRoutes(allowWrites) {
27
+ return {
28
+ "/": ["text/html; charset=utf-8", PAGE_HTML],
29
+ "/app.js": ["text/javascript; charset=utf-8", allowWrites ? pageJs(true) : PAGE_JS],
30
+ "/app.css": ["text/css; charset=utf-8", allowWrites ? pageCss(true) : PAGE_CSS],
31
+ };
32
+ }
27
33
  /**
28
34
  * A header as sent, once — read from `headersDistinct`, because Node keeps only the first `Host` or `Authorization`
29
35
  * of a request that gives two. Given twice, it reads as one value no allowed spelling equals, whichever came first.
@@ -37,6 +43,10 @@ export function startUi(opts) {
37
43
  const token = opts.token ?? randomBytes(32).toString("base64url");
38
44
  const want = Buffer.from(`Bearer ${token}`, "utf8");
39
45
  const run = opts.route ?? defaultRoute;
46
+ const allowWrites = opts.allowWrites === true;
47
+ const deps = { home: opts.home, version: opts.version, allowWrites };
48
+ // Built once: the script and stylesheet the page needs for this run.
49
+ const statics = staticRoutes(allowWrites);
40
50
  // One data request at a time: each loads a Forge and plans a workspace.
41
51
  let queue = Promise.resolve();
42
52
  let port = opts.port;
@@ -55,47 +65,124 @@ export function startUi(opts) {
55
65
  const json = (status, body, extra = {}) => send(status, "application/json; charset=utf-8", JSON.stringify(body), extra);
56
66
  // Every refusal is the same bytes: which check refused is not said.
57
67
  const forbidden = () => json(403, { error: "forbidden" });
58
- if (req.method !== "GET")
68
+ const enqueue = (request, pattern) => {
69
+ // One request's failure must neither end the process nor stop the queue (see the catch at the end).
70
+ queue = queue.then(async () => {
71
+ // Work still queued when the server closed is dropped: its connection is gone, and nothing should keep loading.
72
+ if (closed)
73
+ return;
74
+ try {
75
+ const answer = await run(request, deps);
76
+ json(answer.status, answer.body);
77
+ }
78
+ catch (e) {
79
+ // The pattern, never the request's text; the browser learns nothing of the message.
80
+ opts.onError(`ui: ${pattern}: ${errorText(e).split("\n")[0]}`);
81
+ json(500, { error: "internal error" });
82
+ }
83
+ }).catch(() => {
84
+ // Only the catch above can throw: a failing `onError`, or an answer that can no longer be written. Nothing
85
+ // more can be said then; the connection is closed rather than left unanswered, and the queue goes on.
86
+ res.destroy();
87
+ });
88
+ };
89
+ const method = req.method;
90
+ if (method !== "GET" && method !== "POST") {
91
+ return json(405, { error: allowWrites ? "GET or POST only" : "GET only" }, { Allow: allowWrites ? "GET, POST" : "GET" });
92
+ }
93
+ if (method === "POST" && !allowWrites) {
59
94
  return json(405, { error: "GET only" }, { Allow: "GET" });
95
+ }
60
96
  const target = req.url ?? "/";
61
97
  if (Buffer.byteLength(target, "utf8") > MAX_TARGET_BYTES)
62
98
  return json(414, { error: "request too long" });
63
99
  if (!hostAllowed(one(req, "host"), port))
64
100
  return forbidden();
65
- if (!originAllowed(one(req, "origin"), port) || !siteAllowed(one(req, "sec-fetch-site")))
66
- return forbidden();
101
+ // A POST needs Origin present and exact; a GET may omit it (a navigation or a same-origin fetch sends none).
102
+ const origin = one(req, "origin");
103
+ const site = one(req, "sec-fetch-site");
104
+ if (method === "GET") {
105
+ if (!originAllowed(origin, port) || !siteAllowed(site))
106
+ return forbidden();
107
+ }
108
+ else {
109
+ if (origin === undefined || !names(port).some((n) => origin === `http://${n}`))
110
+ return forbidden();
111
+ if (site !== "same-origin")
112
+ return forbidden();
113
+ }
67
114
  // The path is split from the query by hand: no URL is built from the request.
68
115
  const q = target.indexOf("?");
69
116
  const path = q === -1 ? target : target.slice(0, q);
70
- const page = Object.hasOwn(STATIC, path) ? STATIC[path] : undefined;
71
- if (page)
117
+ const page = Object.hasOwn(statics, path) ? statics[path] : undefined;
118
+ if (page) {
119
+ if (method === "POST")
120
+ return json(405, { error: "GET only" }, { Allow: "GET" });
72
121
  return send(200, page[0], page[1], path === "/" ? { "Content-Security-Policy": CSP } : {});
122
+ }
73
123
  const pattern = routePattern(path);
74
- if (pattern === null)
124
+ const isWritePattern = pattern !== null && WRITE_PATTERNS.includes(pattern);
125
+ if (pattern === null || (!allowWrites && isWritePattern))
75
126
  return json(404, { error: "not found" });
127
+ if (method === "POST" && !isWritePattern)
128
+ return json(405, { error: "GET only" }, { Allow: "GET" });
129
+ if (method === "GET" && isWritePattern)
130
+ return json(405, { error: "POST only" }, { Allow: "POST" });
76
131
  // The token: in the Authorization header and nowhere else, compared in constant time.
77
132
  const got = Buffer.from(one(req, "authorization") ?? "", "utf8");
78
133
  if (got.length !== want.length || !timingSafeEqual(got, want))
79
134
  return forbidden();
80
- // One request's failure must neither end the process nor stop the queue (see the catch at the end).
81
- queue = queue.then(async () => {
82
- // Work still queued when the server closed is dropped: its connection is gone, and nothing should keep loading.
83
- if (closed)
84
- return;
85
- try {
86
- const answer = await run({ path, query: q === -1 ? "" : target.slice(q + 1) }, { home: opts.home, version: opts.version });
87
- json(answer.status, answer.body);
88
- }
89
- catch (e) {
90
- // The pattern, never the request's text; the browser learns nothing of the message.
91
- opts.onError(`ui: ${pattern}: ${errorText(e).split("\n")[0]}`);
92
- json(500, { error: "internal error" });
135
+ if (method === "POST") {
136
+ const contentType = (one(req, "content-type") ?? "").split(";")[0].trim().toLowerCase();
137
+ if (contentType !== "application/json") {
138
+ return json(415, { error: "Content-Type must be application/json" });
93
139
  }
94
- }).catch(() => {
95
- // Only the catch above can throw: a failing `onError`, or an answer that can no longer be written. Nothing
96
- // more can be said then; the connection is closed rather than left unanswered, and the queue goes on.
97
- res.destroy();
98
- });
140
+ // The body is counted as it arrives; nothing is kept past 4096 bytes. It drains to 'end' (up to 1 MiB) so the 413 reaches the client before the connection closes.
141
+ const action = pattern === "/api/workspaces/<id>/sync" ? "sync" : "discard";
142
+ const chunks = [];
143
+ let bytes = 0;
144
+ let drainBytes = 0;
145
+ let bodyRejected = false;
146
+ let drainCapExceeded = false;
147
+ req.on("data", (chunk) => {
148
+ bytes += chunk.length;
149
+ if (!bodyRejected && bytes > MAX_BODY_BYTES) {
150
+ bodyRejected = true;
151
+ drainBytes = bytes - MAX_BODY_BYTES;
152
+ }
153
+ else if (bodyRejected) {
154
+ drainBytes += chunk.length;
155
+ }
156
+ if (bodyRejected) {
157
+ if (drainBytes > MAX_DRAIN_BYTES && !drainCapExceeded) {
158
+ drainCapExceeded = true;
159
+ json(413, { error: "body too large" }, { Connection: "close" });
160
+ res.once("finish", () => req.destroy());
161
+ }
162
+ return;
163
+ }
164
+ chunks.push(chunk);
165
+ });
166
+ req.on("end", () => {
167
+ if (drainCapExceeded || closed)
168
+ return;
169
+ if (bodyRejected) {
170
+ json(413, { error: "body too large" }, { Connection: "close" });
171
+ return;
172
+ }
173
+ const text = Buffer.concat(chunks).toString("utf8");
174
+ const body = parseWriteBody(action, text);
175
+ if (body === null) {
176
+ json(400, { error: "bad request" });
177
+ return;
178
+ }
179
+ enqueue({ path, query: q === -1 ? "" : target.slice(q + 1), method: "POST", body }, pattern);
180
+ });
181
+ // A client that goes away mid-body: nothing to answer, and no unhandled error.
182
+ req.on("error", () => { });
183
+ return;
184
+ }
185
+ enqueue({ path, query: q === -1 ? "" : target.slice(q + 1), method: "GET" }, pattern);
99
186
  });
100
187
  server.headersTimeout = 10_000;
101
188
  server.requestTimeout = 30_000;
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/ui/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/ui/server.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "craftar",
3
- "version": "0.36.0",
3
+ "version": "0.37.0",
4
4
  "description": "Craft, sync and convert AI-coding workspace harnesses across clients and tools.",
5
5
  "license": "MIT",
6
6
  "type": "module",