ledung 1.3.0 → 1.4.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/CHANGELOG.md CHANGED
@@ -10,6 +10,7 @@ that changes `src/`, `web/` (not `web/dist/`) or `scripts/` without one (a commi
10
10
  is nothing user-facing in it).
11
11
 
12
12
  ## 2026-11-02
13
+ - A request whose address doesn't parse is now refused with a 400, also on the live connection, without an error in the log (Fluffy-Fluffy-and-Bouncy/Project-Ledung#467)
13
14
  - Started at sign-in on macOS or Linux, or from Ledung.app, Ledung now gets the same PATH as in your terminal, so Update Ledung, Ledung's GitHub features and the tools your sessions use work after a login too; a shell profile that hangs delays the start by about ten seconds instead of stopping it. Switch Start Ledung when I sign in off and on in Settings to get it (#464)
14
15
  - Settings → About has an update channel, Public or Dev: on Dev an npm-installed Ledung gets dev builds before they go to everyone, and Update & restart now checks npm and updates an npm install with one click (#461)
15
16
 
package/dist/cli.js CHANGED
File without changes
package/dist/main.js CHANGED
@@ -15541,12 +15541,16 @@ var LedungServer = class {
15541
15541
  this.handle(req, res).catch((e) => this.fail(res, e));
15542
15542
  });
15543
15543
  server.on("upgrade", (req, socket, head) => {
15544
- const url = new URL(req.url ?? "/", "http://127.0.0.1");
15545
- if (url.pathname !== "/ws" || !this.guard.hostAllowed(req) || !this.guard.originAllowed(req) || !this.guard.mayUse(req)) {
15546
- socket.end("HTTP/1.1 403 Forbidden\r\nConnection: close\r\n\r\n");
15544
+ const refuse = (status) => {
15545
+ socket.end(`HTTP/1.1 ${status}\r
15546
+ Connection: close\r
15547
+ \r
15548
+ `);
15547
15549
  setTimeout(() => socket.destroy(), 1e3).unref();
15548
- return;
15549
- }
15550
+ };
15551
+ const url = requestUrl(req);
15552
+ if (!url) return refuse("400 Bad Request");
15553
+ if (url.pathname !== "/ws" || !this.guard.hostAllowed(req) || !this.guard.originAllowed(req) || !this.guard.mayUse(req)) return refuse("403 Forbidden");
15550
15554
  const device = this.guard.deviceOf(req)?.id ?? null;
15551
15555
  const viaPublic = this.guard.isPublic(req);
15552
15556
  this.wss.handleUpgrade(req, socket, head, (ws) => this.onClient(ws, device, viaPublic));
@@ -15817,8 +15821,9 @@ var LedungServer = class {
15817
15821
  return computers;
15818
15822
  }
15819
15823
  async handle(req, res) {
15824
+ const url = requestUrl(req);
15825
+ if (!url) throw new HttpError(400, "Bad request path.");
15820
15826
  if (!this.guard.hostAllowed(req)) throw new HttpError(403, "Unknown host.");
15821
- const url = new URL(req.url ?? "/", "http://127.0.0.1");
15822
15827
  const remote = this.guard.isPublic(req);
15823
15828
  if (remote) {
15824
15829
  this.publicResponses.add(res);
@@ -16977,6 +16982,15 @@ var LedungServer = class {
16977
16982
  }
16978
16983
  };
16979
16984
  var bodies = /* @__PURE__ */ new WeakMap();
16985
+ var badPathTraced = false;
16986
+ function requestUrl(req) {
16987
+ const url = URL.parse(req.url ?? "/", "http://127.0.0.1");
16988
+ if (!url && !badPathTraced) {
16989
+ badPathTraced = true;
16990
+ exercisedLine("EXERCISED #467 refused a request path that does not parse");
16991
+ }
16992
+ return url;
16993
+ }
16980
16994
  function fromThisComputer(req) {
16981
16995
  const from = req.socket.remoteAddress ?? "";
16982
16996
  return from === "::1" || from.startsWith("127.") || from.startsWith("::ffff:127.");
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "ledung",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "ledung",
9
- "version": "1.3.0",
9
+ "version": "1.4.0",
10
10
  "license": "AGPL-3.0-only",
11
11
  "dependencies": {
12
12
  "@anthropic-ai/claude-agent-sdk": "0.3.295",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ledung",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "license": "AGPL-3.0-only",
5
5
  "author": "Project Ledung <martin@projectledung.com>",
6
6
  "description": "Runs several Claude Code sessions locally and shows them in one place.",