theokit 0.6.0 → 0.7.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/{actions-virtual-module-DL74V6SR.js → actions-virtual-module-4WVKHQ2X.js} +5 -2
- package/dist/actions-virtual-module-4WVKHQ2X.js.map +1 -0
- package/dist/{actions-virtual-module-ZDD54ZZE.js → actions-virtual-module-LTOXBSCF.js} +16 -2
- package/dist/actions-virtual-module-LTOXBSCF.js.map +1 -0
- package/dist/{app-typed-client-4M4NVSK3.js → app-typed-client-4N5OGNOQ.js} +15 -4
- package/dist/app-typed-client-4N5OGNOQ.js.map +1 -0
- package/dist/{app-typed-client-4GIKUKRT.js → app-typed-client-SAETWZT5.js} +5 -4
- package/dist/app-typed-client-SAETWZT5.js.map +1 -0
- package/dist/{build-ZZAQV2ES.js → build-KQD2EDU4.js} +5 -6
- package/dist/build-KQD2EDU4.js.map +1 -0
- package/dist/chunk-223EFY5X.js +469 -0
- package/dist/chunk-223EFY5X.js.map +1 -0
- package/dist/{chunk-HDA6M7P4.js → chunk-3LVRAGAZ.js} +3 -5
- package/dist/{chunk-4NLIESWK.js → chunk-4I47JW5O.js} +24 -417
- package/dist/chunk-4I47JW5O.js.map +1 -0
- package/dist/{chunk-P2RS3WWY.js → chunk-6FYD34NX.js} +194 -22
- package/dist/chunk-6FYD34NX.js.map +1 -0
- package/dist/{chunk-SVSUUK4H.js → chunk-6VSKLYT6.js} +7 -9
- package/dist/chunk-6VSKLYT6.js.map +1 -0
- package/dist/chunk-CBGRFVF5.js +421 -0
- package/dist/chunk-CBGRFVF5.js.map +1 -0
- package/dist/{chunk-B3L3TJVF.js → chunk-JBCHWRKF.js} +50 -50
- package/dist/chunk-JBCHWRKF.js.map +1 -0
- package/dist/{chunk-XMS5VRIK.js → chunk-JQSFBJR5.js} +3 -3
- package/dist/chunk-JQSFBJR5.js.map +1 -0
- package/dist/{chunk-D4SV7JOG.js → chunk-MV4LKTW6.js} +97 -135
- package/dist/chunk-MV4LKTW6.js.map +1 -0
- package/dist/chunk-PBEH6NXR.js +44 -0
- package/dist/chunk-PBEH6NXR.js.map +1 -0
- package/dist/chunk-PPPR5DGR.js +1 -0
- package/dist/cli/index.js +5 -5
- package/dist/client/index.d.ts +81 -7
- package/dist/client/index.js +111 -3
- package/dist/client/index.js.map +1 -1
- package/dist/{dev-MHCQ5RD7.js → dev-NDEZA2MP.js} +8 -6
- package/dist/dev-NDEZA2MP.js.map +1 -0
- package/dist/{dev-emit-6DJUK6DT.js → dev-emit-O4EGOSNV.js} +2 -4
- package/dist/{dev-emit-6DJUK6DT.js.map → dev-emit-O4EGOSNV.js.map} +1 -1
- package/dist/{dev-emit-4WG3B5BM.js → dev-emit-OUPI7NAQ.js} +3 -4
- package/dist/{dev-emit-4WG3B5BM.js.map → dev-emit-OUPI7NAQ.js.map} +1 -1
- package/dist/{dist-KRW6OVD4.js → dist-6GPD6WCU.js} +10231 -8164
- package/dist/dist-6GPD6WCU.js.map +1 -0
- package/dist/{index-CuHICqb9.d.ts → index-DWZF8uQD.d.ts} +132 -132
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/dist/{lib-NST3PNZX.js → lib-JBI3XXH3.js} +27 -27
- package/dist/{lib-NST3PNZX.js.map → lib-JBI3XXH3.js.map} +1 -1
- package/dist/{openapi-KSY272CW.js → openapi-NXGRXABL.js} +3 -4
- package/dist/{openapi-KSY272CW.js.map → openapi-NXGRXABL.js.map} +1 -1
- package/dist/{routes-NWJA5L5I.js → routes-6A5XFGF7.js} +4 -6
- package/dist/routes-6A5XFGF7.js.map +1 -0
- package/dist/server/auth/index.d.ts +20 -20
- package/dist/server/http/index.d.ts +2 -2
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +9 -13
- package/dist/server/index.js.map +1 -1
- package/dist/server/scan/index.d.ts +13 -13
- package/dist/server/scan/index.js +8 -12
- package/dist/server/security/index.d.ts +69 -69
- package/dist/server/security/index.js +1 -1
- package/dist/{start-OAAAQ7Z4.js → start-SPFWOGHL.js} +14 -14
- package/dist/vite-plugin/index.js +4 -4
- package/dist/{vite-plugin-IF2O6BJV.js → vite-plugin-43KQU5S7.js} +7 -5
- package/dist/vite-plugin-43KQU5S7.js.map +1 -0
- package/package.json +19 -19
- package/dist/actions-virtual-module-DL74V6SR.js.map +0 -1
- package/dist/actions-virtual-module-ZDD54ZZE.js.map +0 -1
- package/dist/app-typed-client-4GIKUKRT.js.map +0 -1
- package/dist/app-typed-client-4M4NVSK3.js.map +0 -1
- package/dist/build-ZZAQV2ES.js.map +0 -1
- package/dist/chunk-4NLIESWK.js.map +0 -1
- package/dist/chunk-B3L3TJVF.js.map +0 -1
- package/dist/chunk-D4SV7JOG.js.map +0 -1
- package/dist/chunk-GPF64ENM.js +0 -73
- package/dist/chunk-HDA6M7P4.js.map +0 -1
- package/dist/chunk-OLPB36O2.js +0 -259
- package/dist/chunk-OLPB36O2.js.map +0 -1
- package/dist/chunk-P2RS3WWY.js.map +0 -1
- package/dist/chunk-P3SGM4NR.js +0 -156
- package/dist/chunk-P3SGM4NR.js.map +0 -1
- package/dist/chunk-SVSUUK4H.js.map +0 -1
- package/dist/chunk-UVHRD33F.js +0 -181
- package/dist/chunk-UVHRD33F.js.map +0 -1
- package/dist/chunk-XMS5VRIK.js.map +0 -1
- package/dist/dev-MHCQ5RD7.js.map +0 -1
- package/dist/dist-KRW6OVD4.js.map +0 -1
- package/dist/routes-NWJA5L5I.js.map +0 -1
- package/dist/{chunk-GPF64ENM.js.map → chunk-3LVRAGAZ.js.map} +0 -0
- package/dist/{vite-plugin-IF2O6BJV.js.map → chunk-PPPR5DGR.js.map} +0 -0
- package/dist/{module-loader-Cfz7dgCP.d.ts → match-CfbEFRG4.d.ts} +4 -4
- /package/dist/{start-OAAAQ7Z4.js.map → start-SPFWOGHL.js.map} +0 -0
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import "tsx/esm";
|
|
3
|
+
import {
|
|
4
|
+
resolveTransformer
|
|
5
|
+
} from "./chunk-PBEH6NXR.js";
|
|
6
|
+
import {
|
|
7
|
+
loadConfig
|
|
8
|
+
} from "./chunk-IHMJV2OK.js";
|
|
9
|
+
import {
|
|
10
|
+
BATCH_PATH,
|
|
11
|
+
CSP_REPORT_PATH,
|
|
12
|
+
CsrfReadinessStore,
|
|
13
|
+
TRACE_HEADER,
|
|
14
|
+
createCorsHandler,
|
|
15
|
+
extractTraceId,
|
|
16
|
+
handleBatchRequest,
|
|
17
|
+
handleCspReport,
|
|
18
|
+
handleCsrfReadiness
|
|
19
|
+
} from "./chunk-CBGRFVF5.js";
|
|
3
20
|
import {
|
|
4
21
|
applySecurityHeaders,
|
|
5
22
|
createPluginRunnerFromConfig,
|
|
@@ -10,13 +27,8 @@ import {
|
|
|
10
27
|
findSuggestion,
|
|
11
28
|
generateNonce,
|
|
12
29
|
logRequest,
|
|
13
|
-
resolveTransformer,
|
|
14
|
-
safeAudit,
|
|
15
30
|
sendError
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import {
|
|
18
|
-
loadConfig
|
|
19
|
-
} from "./chunk-IHMJV2OK.js";
|
|
31
|
+
} from "./chunk-MV4LKTW6.js";
|
|
20
32
|
import {
|
|
21
33
|
buildServicesProxyConfig
|
|
22
34
|
} from "./chunk-CCVC6P6B.js";
|
|
@@ -29,12 +41,10 @@ import {
|
|
|
29
41
|
} from "./chunk-IEES3CHD.js";
|
|
30
42
|
import {
|
|
31
43
|
matchRoute,
|
|
44
|
+
scanServerActions,
|
|
32
45
|
scanServerRoutes,
|
|
33
46
|
scanWebSocketRoutes
|
|
34
|
-
} from "./chunk-
|
|
35
|
-
import {
|
|
36
|
-
scanServerActions
|
|
37
|
-
} from "./chunk-UVHRD33F.js";
|
|
47
|
+
} from "./chunk-6FYD34NX.js";
|
|
38
48
|
|
|
39
49
|
// src/vite-plugin/index.ts
|
|
40
50
|
import { existsSync as existsSync7 } from "fs";
|
|
@@ -285,54 +295,6 @@ function broadcastRouteManifest(tree) {
|
|
|
285
295
|
broadcastToDevtools("theo:devtools:manifest", manifest);
|
|
286
296
|
}
|
|
287
297
|
|
|
288
|
-
// src/server/security/csrf-readiness-store.ts
|
|
289
|
-
var CsrfReadinessStore = class _CsrfReadinessStore {
|
|
290
|
-
static MAX_ENTRIES = 1e3;
|
|
291
|
-
entries = /* @__PURE__ */ new Map();
|
|
292
|
-
keyFor(event) {
|
|
293
|
-
return `${event.method}\0${event.path}\0${event.reason}`;
|
|
294
|
-
}
|
|
295
|
-
record(event) {
|
|
296
|
-
const key = this.keyFor(event);
|
|
297
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
298
|
-
const existing = this.entries.get(key);
|
|
299
|
-
if (existing) {
|
|
300
|
-
existing.count++;
|
|
301
|
-
existing.lastSeen = now;
|
|
302
|
-
return;
|
|
303
|
-
}
|
|
304
|
-
if (this.entries.size >= _CsrfReadinessStore.MAX_ENTRIES) {
|
|
305
|
-
const firstKey = this.entries.keys().next().value;
|
|
306
|
-
if (firstKey !== void 0) this.entries.delete(firstKey);
|
|
307
|
-
}
|
|
308
|
-
this.entries.set(key, { count: 1, firstSeen: now, lastSeen: now });
|
|
309
|
-
}
|
|
310
|
-
summary() {
|
|
311
|
-
let total = 0;
|
|
312
|
-
const routes = [];
|
|
313
|
-
for (const [key, entry] of this.entries) {
|
|
314
|
-
const [method, path, reason] = key.split("\0");
|
|
315
|
-
routes.push({
|
|
316
|
-
method,
|
|
317
|
-
path,
|
|
318
|
-
reason,
|
|
319
|
-
count: entry.count,
|
|
320
|
-
firstSeen: entry.firstSeen,
|
|
321
|
-
lastSeen: entry.lastSeen
|
|
322
|
-
});
|
|
323
|
-
total += entry.count;
|
|
324
|
-
}
|
|
325
|
-
return {
|
|
326
|
-
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
327
|
-
totalEvents: total,
|
|
328
|
-
routes
|
|
329
|
-
};
|
|
330
|
-
}
|
|
331
|
-
reset() {
|
|
332
|
-
this.entries.clear();
|
|
333
|
-
}
|
|
334
|
-
};
|
|
335
|
-
|
|
336
298
|
// src/vite-plugin/action-middleware.ts
|
|
337
299
|
import { randomUUID } from "crypto";
|
|
338
300
|
var PREFIX = "/api/__actions/";
|
|
@@ -416,361 +378,6 @@ function createActionMiddleware(vite, serverDir, options) {
|
|
|
416
378
|
};
|
|
417
379
|
}
|
|
418
380
|
|
|
419
|
-
// src/server/http/batch-handler.ts
|
|
420
|
-
import { z } from "zod";
|
|
421
|
-
var STRIPPED_HEADERS = [
|
|
422
|
-
"authorization",
|
|
423
|
-
"cookie",
|
|
424
|
-
"x-forwarded-for",
|
|
425
|
-
"x-forwarded-host",
|
|
426
|
-
"x-forwarded-proto",
|
|
427
|
-
"x-real-ip",
|
|
428
|
-
"host"
|
|
429
|
-
];
|
|
430
|
-
var BATCH_PATH = "/api/__theo_batch__";
|
|
431
|
-
var DEFAULT_MAX_BATCH = 32;
|
|
432
|
-
var batchRequestSchema = z.object({
|
|
433
|
-
path: z.string().min(1),
|
|
434
|
-
method: z.string().min(1),
|
|
435
|
-
query: z.record(z.string(), z.unknown()).optional(),
|
|
436
|
-
body: z.unknown().optional(),
|
|
437
|
-
headers: z.record(z.string(), z.string()).optional()
|
|
438
|
-
});
|
|
439
|
-
var batchPayloadSchema = z.object({
|
|
440
|
-
requests: z.array(batchRequestSchema).min(1)
|
|
441
|
-
});
|
|
442
|
-
function sanitizeItemHeaders(itemHeaders, outerHeaders) {
|
|
443
|
-
const out = {};
|
|
444
|
-
if (itemHeaders) {
|
|
445
|
-
for (const [k, v] of Object.entries(itemHeaders)) {
|
|
446
|
-
const lower = k.toLowerCase();
|
|
447
|
-
if (!STRIPPED_HEADERS.includes(lower)) {
|
|
448
|
-
out[lower] = v;
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
if (outerHeaders) {
|
|
453
|
-
for (const stripped of STRIPPED_HEADERS) {
|
|
454
|
-
if (Object.hasOwn(outerHeaders, stripped)) {
|
|
455
|
-
out[stripped] = outerHeaders[stripped];
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
return out;
|
|
460
|
-
}
|
|
461
|
-
async function handleBatchRequest(payload, options) {
|
|
462
|
-
const parsed = batchPayloadSchema.parse(payload);
|
|
463
|
-
const max = options.max ?? DEFAULT_MAX_BATCH;
|
|
464
|
-
if (parsed.requests.length > max) {
|
|
465
|
-
throw new Error(`Batch size ${parsed.requests.length} exceeds max ${max}`);
|
|
466
|
-
}
|
|
467
|
-
const results = [];
|
|
468
|
-
for (const item of parsed.requests) {
|
|
469
|
-
const sanitized = {
|
|
470
|
-
...item,
|
|
471
|
-
headers: sanitizeItemHeaders(item.headers, options.outerHeaders)
|
|
472
|
-
};
|
|
473
|
-
try {
|
|
474
|
-
const r = await options.execute(sanitized);
|
|
475
|
-
results.push(r);
|
|
476
|
-
} catch (err) {
|
|
477
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
478
|
-
results.push({ error: { message } });
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
return { results };
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
// src/server/http/cors.ts
|
|
485
|
-
var DEFAULT_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"];
|
|
486
|
-
var DEFAULT_ALLOWED_HEADERS = ["Content-Type", "X-Theo-Action", "Authorization"];
|
|
487
|
-
var DEFAULT_MAX_AGE = 600;
|
|
488
|
-
function readOrigin(req) {
|
|
489
|
-
const raw = req.headers.origin;
|
|
490
|
-
if (raw === void 0) return void 0;
|
|
491
|
-
if (Array.isArray(raw)) {
|
|
492
|
-
return raw.find((v) => typeof v === "string" && v.length > 0);
|
|
493
|
-
}
|
|
494
|
-
return raw;
|
|
495
|
-
}
|
|
496
|
-
function matchesOrigin(origin, allowed) {
|
|
497
|
-
if (allowed === "*") return true;
|
|
498
|
-
if (typeof allowed === "string") return origin === allowed;
|
|
499
|
-
if (allowed instanceof RegExp) {
|
|
500
|
-
allowed.lastIndex = 0;
|
|
501
|
-
return allowed.test(origin);
|
|
502
|
-
}
|
|
503
|
-
if (Array.isArray(allowed)) {
|
|
504
|
-
for (const entry of allowed) {
|
|
505
|
-
if (typeof entry === "string" && origin === entry) return true;
|
|
506
|
-
if (entry instanceof RegExp) {
|
|
507
|
-
entry.lastIndex = 0;
|
|
508
|
-
if (entry.test(origin)) return true;
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
return false;
|
|
512
|
-
}
|
|
513
|
-
if (typeof allowed === "function") {
|
|
514
|
-
try {
|
|
515
|
-
return allowed(origin);
|
|
516
|
-
} catch {
|
|
517
|
-
return false;
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
return false;
|
|
521
|
-
}
|
|
522
|
-
function createCorsHandler(config) {
|
|
523
|
-
const methods = (config.methods ?? DEFAULT_METHODS).slice();
|
|
524
|
-
const allowedHeaders = (config.allowedHeaders ?? DEFAULT_ALLOWED_HEADERS).slice();
|
|
525
|
-
const maxAge = String(config.maxAge ?? DEFAULT_MAX_AGE);
|
|
526
|
-
const credentials = config.credentials === true;
|
|
527
|
-
return {
|
|
528
|
-
handlePreflight(req, res) {
|
|
529
|
-
if (req.method !== "OPTIONS") return false;
|
|
530
|
-
const acMethod = req.headers["access-control-request-method"];
|
|
531
|
-
if (!acMethod) return false;
|
|
532
|
-
const origin = readOrigin(req);
|
|
533
|
-
if (!origin) return false;
|
|
534
|
-
if (!matchesOrigin(origin, config.origins)) {
|
|
535
|
-
res.statusCode = 403;
|
|
536
|
-
res.end();
|
|
537
|
-
return true;
|
|
538
|
-
}
|
|
539
|
-
res.setHeader("Access-Control-Allow-Origin", origin);
|
|
540
|
-
res.setHeader("Access-Control-Allow-Methods", methods.join(", "));
|
|
541
|
-
res.setHeader("Access-Control-Allow-Headers", allowedHeaders.join(", "));
|
|
542
|
-
res.setHeader("Access-Control-Max-Age", maxAge);
|
|
543
|
-
res.setHeader("Vary", "Origin");
|
|
544
|
-
if (credentials) res.setHeader("Access-Control-Allow-Credentials", "true");
|
|
545
|
-
res.statusCode = 204;
|
|
546
|
-
res.end();
|
|
547
|
-
return true;
|
|
548
|
-
},
|
|
549
|
-
applyHeaders(req, res) {
|
|
550
|
-
const origin = readOrigin(req);
|
|
551
|
-
if (!origin) return;
|
|
552
|
-
if (!matchesOrigin(origin, config.origins)) return;
|
|
553
|
-
res.setHeader("Access-Control-Allow-Origin", origin);
|
|
554
|
-
res.setHeader("Vary", "Origin");
|
|
555
|
-
if (credentials) res.setHeader("Access-Control-Allow-Credentials", "true");
|
|
556
|
-
if (config.exposedHeaders && config.exposedHeaders.length > 0) {
|
|
557
|
-
res.setHeader("Access-Control-Expose-Headers", config.exposedHeaders.join(", "));
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
};
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
// src/server/http/trace-context.ts
|
|
564
|
-
var TRACE_HEADER = "x-trace-id";
|
|
565
|
-
var TRACE_PARENT_HEADER = "traceparent";
|
|
566
|
-
var REQUEST_ID_HEADER = "x-request-id";
|
|
567
|
-
var TRACEPARENT_RE = /^00-([0-9a-f]{32})-([0-9a-f]{16})-[0-9a-f]{2}$/;
|
|
568
|
-
function parseTraceparent(value) {
|
|
569
|
-
if (!value) return null;
|
|
570
|
-
const m = TRACEPARENT_RE.exec(value);
|
|
571
|
-
if (!m) return null;
|
|
572
|
-
const traceId = m[1];
|
|
573
|
-
if (/^0+$/.test(traceId)) return null;
|
|
574
|
-
return traceId;
|
|
575
|
-
}
|
|
576
|
-
function pickHeader(value) {
|
|
577
|
-
if (Array.isArray(value)) {
|
|
578
|
-
for (const v of value) {
|
|
579
|
-
if (typeof v === "string" && v.length > 0) return v;
|
|
580
|
-
}
|
|
581
|
-
return null;
|
|
582
|
-
}
|
|
583
|
-
if (typeof value === "string" && value.length > 0) return value;
|
|
584
|
-
return null;
|
|
585
|
-
}
|
|
586
|
-
function resolveTraceIdFromHeaders(traceparent, requestId) {
|
|
587
|
-
if (traceparent !== null) {
|
|
588
|
-
const parsed = parseTraceparent(traceparent);
|
|
589
|
-
if (parsed !== null) return parsed;
|
|
590
|
-
}
|
|
591
|
-
if (requestId !== null) return requestId;
|
|
592
|
-
return globalThis.crypto.randomUUID();
|
|
593
|
-
}
|
|
594
|
-
function extractTraceId(req) {
|
|
595
|
-
return resolveTraceIdFromHeaders(
|
|
596
|
-
pickHeader(req.headers[TRACE_PARENT_HEADER]),
|
|
597
|
-
pickHeader(req.headers[REQUEST_ID_HEADER])
|
|
598
|
-
);
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
// src/server/security/csp-report.ts
|
|
602
|
-
var CSP_REPORT_PATH = "/__theo/csp-report";
|
|
603
|
-
var MAX_BODY = 16 * 1024;
|
|
604
|
-
function pickHeader2(value) {
|
|
605
|
-
if (typeof value === "string") return value;
|
|
606
|
-
if (Array.isArray(value) && value.length > 0) return value[0];
|
|
607
|
-
return "";
|
|
608
|
-
}
|
|
609
|
-
function toStringSafe(value, fallback = "(missing)") {
|
|
610
|
-
if (typeof value === "string") return value;
|
|
611
|
-
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
612
|
-
return fallback;
|
|
613
|
-
}
|
|
614
|
-
function normalizeLegacy(raw) {
|
|
615
|
-
return {
|
|
616
|
-
blockedUrl: toStringSafe(raw["blocked-uri"]),
|
|
617
|
-
documentUrl: toStringSafe(raw["document-uri"]),
|
|
618
|
-
violatedDirective: toStringSafe(raw["violated-directive"]),
|
|
619
|
-
effectiveDirective: typeof raw["effective-directive"] === "string" ? raw["effective-directive"] : void 0,
|
|
620
|
-
originalPolicy: typeof raw["original-policy"] === "string" ? raw["original-policy"] : void 0,
|
|
621
|
-
disposition: raw.disposition === "enforce" || raw.disposition === "report" ? raw.disposition : void 0,
|
|
622
|
-
statusCode: typeof raw["status-code"] === "number" ? raw["status-code"] : void 0,
|
|
623
|
-
sourceFile: typeof raw["source-file"] === "string" ? raw["source-file"] : void 0,
|
|
624
|
-
lineNumber: typeof raw["line-number"] === "number" ? raw["line-number"] : void 0,
|
|
625
|
-
columnNumber: typeof raw["column-number"] === "number" ? raw["column-number"] : void 0
|
|
626
|
-
};
|
|
627
|
-
}
|
|
628
|
-
function normalizeNew(entry) {
|
|
629
|
-
if (!entry || typeof entry !== "object") return null;
|
|
630
|
-
const body = entry.body;
|
|
631
|
-
if (!body || typeof body !== "object") return null;
|
|
632
|
-
const b = body;
|
|
633
|
-
return {
|
|
634
|
-
blockedUrl: toStringSafe(b.blockedURL),
|
|
635
|
-
documentUrl: toStringSafe(b.documentURL),
|
|
636
|
-
violatedDirective: toStringSafe(b.violatedDirective),
|
|
637
|
-
effectiveDirective: typeof b.effectiveDirective === "string" ? b.effectiveDirective : void 0,
|
|
638
|
-
originalPolicy: typeof b.originalPolicy === "string" ? b.originalPolicy : void 0,
|
|
639
|
-
disposition: b.disposition === "enforce" || b.disposition === "report" ? b.disposition : void 0,
|
|
640
|
-
statusCode: typeof b.statusCode === "number" ? b.statusCode : void 0,
|
|
641
|
-
sourceFile: typeof b.sourceFile === "string" ? b.sourceFile : void 0,
|
|
642
|
-
lineNumber: typeof b.lineNumber === "number" ? b.lineNumber : void 0,
|
|
643
|
-
columnNumber: typeof b.columnNumber === "number" ? b.columnNumber : void 0
|
|
644
|
-
};
|
|
645
|
-
}
|
|
646
|
-
async function readBody(req, maxBytes) {
|
|
647
|
-
return await new Promise((resolve8, reject) => {
|
|
648
|
-
const chunks = [];
|
|
649
|
-
let total = 0;
|
|
650
|
-
req.on("data", (chunk) => {
|
|
651
|
-
total += chunk.length;
|
|
652
|
-
if (total > maxBytes) {
|
|
653
|
-
reject(new Error("body too large"));
|
|
654
|
-
req.destroy();
|
|
655
|
-
return;
|
|
656
|
-
}
|
|
657
|
-
chunks.push(chunk);
|
|
658
|
-
});
|
|
659
|
-
req.on("end", () => {
|
|
660
|
-
resolve8(Buffer.concat(chunks).toString("utf8"));
|
|
661
|
-
});
|
|
662
|
-
req.on("error", reject);
|
|
663
|
-
});
|
|
664
|
-
}
|
|
665
|
-
async function handleCspReport(req, res, opts) {
|
|
666
|
-
const ctHeader = req.headers["content-type"];
|
|
667
|
-
const ct = pickHeader2(ctHeader);
|
|
668
|
-
let raw;
|
|
669
|
-
try {
|
|
670
|
-
raw = await readBody(req, MAX_BODY);
|
|
671
|
-
} catch {
|
|
672
|
-
res.statusCode = 413;
|
|
673
|
-
res.end();
|
|
674
|
-
return;
|
|
675
|
-
}
|
|
676
|
-
let violations;
|
|
677
|
-
try {
|
|
678
|
-
if (ct.startsWith("application/csp-report")) {
|
|
679
|
-
const parsed = JSON.parse(raw);
|
|
680
|
-
const inner = parsed["csp-report"];
|
|
681
|
-
if (!inner || typeof inner !== "object") {
|
|
682
|
-
res.statusCode = 204;
|
|
683
|
-
res.end();
|
|
684
|
-
return;
|
|
685
|
-
}
|
|
686
|
-
violations = [normalizeLegacy(inner)];
|
|
687
|
-
} else if (ct.startsWith("application/reports+json")) {
|
|
688
|
-
const parsed = JSON.parse(raw);
|
|
689
|
-
const entries = Array.isArray(parsed) ? parsed : [];
|
|
690
|
-
violations = entries.map((e) => normalizeNew(e)).filter((v) => v !== null);
|
|
691
|
-
} else {
|
|
692
|
-
res.statusCode = 415;
|
|
693
|
-
res.end();
|
|
694
|
-
return;
|
|
695
|
-
}
|
|
696
|
-
} catch {
|
|
697
|
-
res.statusCode = 400;
|
|
698
|
-
res.end();
|
|
699
|
-
return;
|
|
700
|
-
}
|
|
701
|
-
for (const v of violations) {
|
|
702
|
-
safeAudit(opts.auditLogger, {
|
|
703
|
-
action: "csp.violation",
|
|
704
|
-
metadata: v
|
|
705
|
-
});
|
|
706
|
-
try {
|
|
707
|
-
opts.devtoolsDispatcher?.onCspViolation?.(v);
|
|
708
|
-
} catch {
|
|
709
|
-
}
|
|
710
|
-
try {
|
|
711
|
-
opts.onViolation?.(v);
|
|
712
|
-
} catch {
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
res.statusCode = 204;
|
|
716
|
-
res.end();
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
// src/server/security/csrf-readiness-endpoint.ts
|
|
720
|
-
var CSRF_READINESS_PATH = "/__theo/csrf-readiness";
|
|
721
|
-
var CSRF_READINESS_RESET_PATH = "/__theo/csrf-readiness/reset";
|
|
722
|
-
function originMatchesHost(req) {
|
|
723
|
-
const origin = req.headers.origin;
|
|
724
|
-
if (typeof origin !== "string") return false;
|
|
725
|
-
const host = req.headers.host;
|
|
726
|
-
if (typeof host !== "string") return false;
|
|
727
|
-
try {
|
|
728
|
-
const parsed = new URL(origin);
|
|
729
|
-
return parsed.host === host;
|
|
730
|
-
} catch {
|
|
731
|
-
return false;
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
function sendJson(res, status, body) {
|
|
735
|
-
res.writeHead(status, { "content-type": "application/json" });
|
|
736
|
-
res.end(JSON.stringify(body));
|
|
737
|
-
}
|
|
738
|
-
function sendNoContent(res) {
|
|
739
|
-
res.writeHead(204);
|
|
740
|
-
res.end();
|
|
741
|
-
}
|
|
742
|
-
function sendError2(res, status, code, message) {
|
|
743
|
-
res.writeHead(status, { "content-type": "application/json" });
|
|
744
|
-
res.end(JSON.stringify({ error: { code, message } }));
|
|
745
|
-
}
|
|
746
|
-
async function handleCsrfReadiness(req, res, store) {
|
|
747
|
-
const url = (req.url ?? "").split("?")[0];
|
|
748
|
-
const method = req.method ?? "GET";
|
|
749
|
-
if (url === CSRF_READINESS_PATH) {
|
|
750
|
-
if (method === "GET") {
|
|
751
|
-
sendJson(res, 200, store.summary());
|
|
752
|
-
return true;
|
|
753
|
-
}
|
|
754
|
-
sendError2(res, 405, "METHOD_NOT_ALLOWED", `Use GET on ${CSRF_READINESS_PATH}`);
|
|
755
|
-
return true;
|
|
756
|
-
}
|
|
757
|
-
if (url === CSRF_READINESS_RESET_PATH) {
|
|
758
|
-
if (method !== "POST") {
|
|
759
|
-
sendError2(res, 405, "METHOD_NOT_ALLOWED", `Use POST on ${CSRF_READINESS_RESET_PATH}`);
|
|
760
|
-
return true;
|
|
761
|
-
}
|
|
762
|
-
const hasHeader = req.headers["x-theo-action"] === "1";
|
|
763
|
-
if (!hasHeader || !originMatchesHost(req)) {
|
|
764
|
-
sendError2(res, 403, "CSRF_INVALID", "Reset requires X-Theo-Action: 1 + same-origin");
|
|
765
|
-
return true;
|
|
766
|
-
}
|
|
767
|
-
store.reset();
|
|
768
|
-
sendNoContent(res);
|
|
769
|
-
return true;
|
|
770
|
-
}
|
|
771
|
-
return false;
|
|
772
|
-
}
|
|
773
|
-
|
|
774
381
|
// src/vite-plugin/api-middleware.ts
|
|
775
382
|
function shouldBypassApiMiddleware(url, prefixes) {
|
|
776
383
|
if (!url.startsWith("/api/")) return true;
|
|
@@ -1145,7 +752,7 @@ async function runConfigureServer(server, ctx) {
|
|
|
1145
752
|
server.watcher.on("unlink", handleRouteChange);
|
|
1146
753
|
if (ctx.resolvedOpenApi !== void 0) {
|
|
1147
754
|
const openApiCfg = ctx.resolvedOpenApi;
|
|
1148
|
-
const { reEmitOpenApi } = await import("./dev-emit-
|
|
755
|
+
const { reEmitOpenApi } = await import("./dev-emit-OUPI7NAQ.js");
|
|
1149
756
|
const openApiServerDir = resolve4(ctx.projectRoot, "server");
|
|
1150
757
|
const openApiDistDir = resolve4(ctx.projectRoot, ctx.resolvedDistDir);
|
|
1151
758
|
const isRouteFileForOpenApi = (file) => file.startsWith(openApiServerDir) && /\.(ts|tsx|js|mjs)$/.test(file);
|
|
@@ -2131,13 +1738,13 @@ async function theoPluginAsync(rootOrOptions) {
|
|
|
2131
1738
|
})
|
|
2132
1739
|
);
|
|
2133
1740
|
}
|
|
2134
|
-
const { appTypedClientPlugin } = await import("./app-typed-client-
|
|
1741
|
+
const { appTypedClientPlugin } = await import("./app-typed-client-SAETWZT5.js");
|
|
2135
1742
|
const appClientPlugin = appTypedClientPlugin({
|
|
2136
1743
|
cwd: projectRoot,
|
|
2137
1744
|
serverDir: resolve7(projectRoot, "server"),
|
|
2138
1745
|
distDir: resolve7(projectRoot, ".theokit")
|
|
2139
1746
|
});
|
|
2140
|
-
const { actionsVirtualModule } = await import("./actions-virtual-module-
|
|
1747
|
+
const { actionsVirtualModule } = await import("./actions-virtual-module-4WVKHQ2X.js");
|
|
2141
1748
|
const actionsPlugin = actionsVirtualModule({
|
|
2142
1749
|
serverDir: resolve7(projectRoot, "server"),
|
|
2143
1750
|
distDir: resolve7(projectRoot, ".theokit")
|
|
@@ -2303,4 +1910,4 @@ export {
|
|
|
2303
1910
|
theoPluginAsync,
|
|
2304
1911
|
theoPlugin
|
|
2305
1912
|
};
|
|
2306
|
-
//# sourceMappingURL=chunk-
|
|
1913
|
+
//# sourceMappingURL=chunk-4I47JW5O.js.map
|