@swissjs/swite 0.3.5 → 0.4.2
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/CHANGELOG.md +30 -0
- package/DIRECTIVE.md +57 -2
- package/__tests__/import-rewriter-bug.test.ts +100 -113
- package/__tests__/security-r001-r002.test.ts +190 -0
- package/dist/build-engine/builder.js +9 -9
- package/dist/cli.js +0 -0
- package/dist/config/config.d.ts +0 -5
- package/dist/config/config.d.ts.map +1 -1
- package/dist/dev-engine/handlers/base-handler.d.ts +6 -0
- package/dist/dev-engine/handlers/base-handler.d.ts.map +1 -1
- package/dist/dev-engine/handlers/base-handler.js +91 -0
- package/dist/dev-engine/handlers/ui-handler.d.ts +0 -1
- package/dist/dev-engine/handlers/ui-handler.d.ts.map +1 -1
- package/dist/dev-engine/handlers/ui-handler.js +2 -64
- package/dist/dev-engine/handlers/uix-handler.d.ts +0 -1
- package/dist/dev-engine/handlers/uix-handler.d.ts.map +1 -1
- package/dist/dev-engine/handlers/uix-handler.js +2 -58
- package/dist/dev-engine/hmr/hmr-client-template.js +111 -111
- package/dist/dev-engine/hmr/hmr.d.ts +10 -1
- package/dist/dev-engine/hmr/hmr.d.ts.map +1 -1
- package/dist/dev-engine/hmr/hmr.js +40 -2
- package/dist/dev-engine/middleware/middleware-setup.js +4 -3
- package/dist/dev-engine/middleware/static-files.d.ts.map +1 -1
- package/dist/dev-engine/middleware/static-files.js +145 -62
- package/dist/dev-engine/pythonDevManager.js +1 -1
- package/dist/dev-engine/router/file-router.d.ts.map +1 -1
- package/dist/dev-engine/router/file-router.js +2 -29
- package/dist/dev-engine/server.d.ts +7 -0
- package/dist/dev-engine/server.d.ts.map +1 -1
- package/dist/dev-engine/server.js +31 -3
- package/dist/kernel/package-finder.d.ts +0 -8
- package/dist/kernel/package-finder.d.ts.map +1 -1
- package/dist/kernel/package-finder.js +2 -2
- package/dist/kernel/package-registry.d.ts +6 -0
- package/dist/kernel/package-registry.d.ts.map +1 -1
- package/dist/kernel/package-registry.js +8 -0
- package/dist/kernel/workspace.d.ts.map +1 -1
- package/dist/kernel/workspace.js +12 -9
- package/docs/architecture/build-pipeline.md +97 -97
- package/docs/architecture/dev-server.md +87 -87
- package/docs/architecture/hmr.md +78 -78
- package/docs/architecture/import-rewriting.md +101 -101
- package/docs/architecture/index.md +16 -16
- package/docs/architecture/python-integration.md +93 -93
- package/docs/architecture/resolution.md +92 -92
- package/docs/cli/build.md +78 -78
- package/docs/cli/dev.md +90 -90
- package/docs/cli/index.md +15 -15
- package/docs/cli/start.md +45 -45
- package/docs/development/contributing.md +74 -74
- package/docs/development/index.md +12 -12
- package/docs/development/internals.md +101 -101
- package/docs/guide/configuration.md +89 -89
- package/docs/guide/index.md +13 -13
- package/docs/guide/project-structure.md +75 -75
- package/docs/guide/quickstart.md +113 -113
- package/docs/index.md +16 -16
- package/package.json +29 -16
- package/src/build-engine/builder.ts +9 -9
- package/src/config/config.ts +0 -5
- package/src/config/env.ts +98 -98
- package/src/dev-engine/handlers/base-handler.ts +109 -0
- package/src/dev-engine/handlers/ui-handler.ts +30 -110
- package/src/dev-engine/handlers/uix-handler.ts +21 -95
- package/src/dev-engine/hmr/hmr-client-template.ts +122 -122
- package/src/dev-engine/hmr/hmr.ts +46 -1
- package/src/dev-engine/middleware/middleware-setup.ts +354 -354
- package/src/dev-engine/middleware/static-files.ts +203 -121
- package/src/dev-engine/pythonDevManager.ts +1 -1
- package/src/dev-engine/router/file-router.ts +2 -45
- package/src/dev-engine/server.ts +33 -3
- package/src/kernel/package-finder.ts +2 -2
- package/src/kernel/package-registry.ts +9 -0
- package/src/kernel/workspace.ts +8 -10
- package/src/resolution/cdn/cdn-fallback.ts +40 -40
- package/src/resolution/path/path-fixup.ts +27 -27
- package/src/resolution/rewriting/import-rewriter.ts +237 -237
- package/src/resolution/symlink-registry.ts +114 -114
|
@@ -13,16 +13,42 @@ export class HMREngine {
|
|
|
13
13
|
private watcher?: chokidar.FSWatcher;
|
|
14
14
|
private clients = new Set<WebSocket>();
|
|
15
15
|
private port: number;
|
|
16
|
+
/** Origins permitted to connect (e.g. "http://localhost:3000"). */
|
|
17
|
+
private allowedOrigins: Set<string>;
|
|
16
18
|
|
|
17
19
|
constructor(
|
|
18
20
|
private root: string,
|
|
19
21
|
hmrPort?: number,
|
|
22
|
+
allowedOrigins: string[] = [],
|
|
20
23
|
) {
|
|
21
24
|
this.port = hmrPort || 24678;
|
|
25
|
+
// Security (R-002): build an origin allowlist.
|
|
26
|
+
// Always allow the two canonical loopback forms so a default dev setup
|
|
27
|
+
// (host: "localhost", port: 3000) works without any extra config.
|
|
28
|
+
this.allowedOrigins = new Set([
|
|
29
|
+
...allowedOrigins,
|
|
30
|
+
]);
|
|
22
31
|
// WebSocketServer will be created in initialize() method
|
|
23
32
|
// This allows async port checking before server creation
|
|
24
33
|
}
|
|
25
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Return true when `origin` is on the allowlist.
|
|
37
|
+
* - Absent / empty origin header → REJECT (not a browser page request).
|
|
38
|
+
* - Exact match (scheme + host + optional port) → ALLOW.
|
|
39
|
+
* - The check is case-insensitive on the scheme+host portion per RFC 6454.
|
|
40
|
+
*/
|
|
41
|
+
private isOriginAllowed(origin: string | undefined): boolean {
|
|
42
|
+
if (!origin) return false;
|
|
43
|
+
// Normalise: strip trailing slash, lower-case scheme+host.
|
|
44
|
+
const normalise = (o: string) => o.replace(/\/$/, "").toLowerCase();
|
|
45
|
+
const candidate = normalise(origin);
|
|
46
|
+
for (const allowed of this.allowedOrigins) {
|
|
47
|
+
if (normalise(allowed) === candidate) return true;
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
|
|
26
52
|
async initialize(): Promise<void> {
|
|
27
53
|
// Check if port is available, if not find a free one
|
|
28
54
|
const isAvailable = await this.checkPortAvailable(this.port);
|
|
@@ -51,7 +77,26 @@ export class HMREngine {
|
|
|
51
77
|
}
|
|
52
78
|
|
|
53
79
|
private setupWebSocket() {
|
|
54
|
-
|
|
80
|
+
// Security (R-002): validate the Origin header on every incoming WebSocket
|
|
81
|
+
// upgrade to prevent cross-site WebSocket hijacking. A malicious page
|
|
82
|
+
// served from a different origin cannot subscribe to HMR events (which
|
|
83
|
+
// include absolute filesystem paths of every changed file).
|
|
84
|
+
//
|
|
85
|
+
// Connections with a missing or non-allowlisted Origin are rejected with
|
|
86
|
+
// a 403 close frame. Same-origin connections from the dev server's own
|
|
87
|
+
// host:port are always allowed via this.allowedOrigins.
|
|
88
|
+
this.wss.on("connection", (ws, req) => {
|
|
89
|
+
const origin = req.headers["origin"];
|
|
90
|
+
if (!this.isOriginAllowed(origin)) {
|
|
91
|
+
console.warn(
|
|
92
|
+
chalk.red(
|
|
93
|
+
`[HMR] Rejected connection from disallowed origin: ${origin ?? "(none)"}`,
|
|
94
|
+
),
|
|
95
|
+
);
|
|
96
|
+
ws.close(1008, "Origin not allowed");
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
55
100
|
this.clients.add(ws);
|
|
56
101
|
console.log(chalk.green("[HMR] Client connected"));
|
|
57
102
|
|