portless 0.15.2 → 0.15.3

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/README.md CHANGED
@@ -36,6 +36,8 @@ The proxy auto-starts when you run an app. A random port (4000-4999) is assigned
36
36
 
37
37
  When auto-starting, portless reuses the configuration (port, TLS, TLDs) from the most recent proxy run, so a restart or reboot does not silently revert to defaults. Explicit env vars (`PORTLESS_PORT`, `PORTLESS_HTTPS`, etc.) always take priority.
38
38
 
39
+ Portless stores per-user state in `~/.portless`. When the proxy runs under sudo, it resolves this path from the invoking user's home so the proxy and unprivileged app processes share the same route registrations.
40
+
39
41
  In non-interactive environments (no TTY, or `CI=1`), portless exits with a descriptive error instead of prompting, so task runners like turborepo and CI scripts fail early with a clear message.
40
42
 
41
43
  ## Configuration
@@ -258,7 +260,7 @@ portless proxy start --no-tls
258
260
  portless trust
259
261
  ```
260
262
 
261
- On Linux, `portless trust` supports Debian/Ubuntu, Arch, Fedora/RHEL/CentOS, and openSUSE (via `update-ca-certificates` or `update-ca-trust`). On Windows, it uses `certutil` to add the CA to the system trust store.
263
+ On Linux, `portless trust` supports Debian/Ubuntu, Arch, Fedora/RHEL/CentOS, and openSUSE (via `update-ca-certificates` or `update-ca-trust`). On Windows, it uses `certutil` to add the CA to the system trust store. On WSL, it updates both the Linux trust store and the Windows current-user Root store so Windows browsers trust portless HTTPS certificates.
262
264
 
263
265
  ## Start at OS startup
264
266
 
@@ -445,7 +447,7 @@ To remove portless data from your machine (proxy state under `~/.portless` and t
445
447
  portless clean
446
448
  ```
447
449
 
448
- macOS/Linux may prompt for `sudo`. Custom certificate paths passed with `--cert` and `--key` are not deleted.
450
+ macOS/Linux may prompt for `sudo`. Custom certificate paths passed with `--cert` and `--key` are not deleted. If trust-store removal fails, portless retains its CA certificate and key so a later `portless clean` can safely retry.
449
451
 
450
452
  ## Safari / DNS
451
453
 
@@ -1,6 +1,32 @@
1
1
  // src/utils.ts
2
2
  import * as fs from "fs";
3
3
  import * as net from "net";
4
+ import * as os from "os";
5
+ import * as path from "path";
6
+ function readPasswdHome(username) {
7
+ try {
8
+ const passwd = fs.readFileSync("/etc/passwd", "utf-8");
9
+ for (const line of passwd.split("\n")) {
10
+ const fields = line.split(":");
11
+ if (fields[0] === username && fields[5]) return fields[5];
12
+ }
13
+ } catch {
14
+ }
15
+ return null;
16
+ }
17
+ function resolveUserHome(options = {}) {
18
+ const platform = options.platform ?? process.platform;
19
+ const env = options.env ?? process.env;
20
+ const homedir2 = options.homedir ?? os.homedir();
21
+ if (platform === "win32") return env.USERPROFILE || homedir2;
22
+ const sudoUser = env.SUDO_USER;
23
+ if (!sudoUser || sudoUser === "root") return homedir2;
24
+ const home = env.HOME;
25
+ if (home && home !== "/root" && home !== "/var/root") return home;
26
+ const passwdHome = (options.passwdHome ?? readPasswdHome)(sudoUser);
27
+ if (passwdHome) return passwdHome;
28
+ return platform === "darwin" ? path.posix.join("/Users", sudoUser) : path.posix.join("/home", sudoUser);
29
+ }
4
30
  function loopbackLookup(_hostname, _options, callback) {
5
31
  callback(null, [
6
32
  { address: "127.0.0.1", family: 4 },
@@ -653,9 +679,9 @@ function createHttpRedirectServer(httpsPort) {
653
679
  // src/hosts.ts
654
680
  import * as fs2 from "fs";
655
681
  import * as dns from "dns";
656
- import * as path from "path";
682
+ import * as path2 from "path";
657
683
  var isWindows = process.platform === "win32";
658
- var HOSTS_PATH = isWindows ? path.join(process.env.SystemRoot ?? "C:\\Windows", "System32", "drivers", "etc", "hosts") : "/etc/hosts";
684
+ var HOSTS_PATH = isWindows ? path2.join(process.env.SystemRoot ?? "C:\\Windows", "System32", "drivers", "etc", "hosts") : "/etc/hosts";
659
685
  var MARKER_START = "# portless-start";
660
686
  var MARKER_END = "# portless-end";
661
687
  function readHostsFile() {
@@ -736,7 +762,7 @@ function checkHostResolution(hostname) {
736
762
 
737
763
  // src/routes.ts
738
764
  import * as fs3 from "fs";
739
- import * as path2 from "path";
765
+ import * as path3 from "path";
740
766
  var STALE_LOCK_THRESHOLD_MS = 1e4;
741
767
  var LOCK_TIMEOUT_MS = 15e3;
742
768
  var LOCK_RETRY_BASE_MS = 10;
@@ -768,10 +794,10 @@ var RouteStore = class _RouteStore {
768
794
  onWarning;
769
795
  constructor(dir, options) {
770
796
  this.dir = dir;
771
- this.routesPath = path2.join(dir, "routes.json");
772
- this.lockPath = path2.join(dir, "routes.lock");
773
- this.pidPath = path2.join(dir, "proxy.pid");
774
- this.portFilePath = path2.join(dir, "proxy.port");
797
+ this.routesPath = path3.join(dir, "routes.json");
798
+ this.lockPath = path3.join(dir, "routes.lock");
799
+ this.pidPath = path3.join(dir, "proxy.pid");
800
+ this.portFilePath = path3.join(dir, "proxy.port");
775
801
  this.onWarning = options?.onWarning;
776
802
  }
777
803
  ensureDir() {
@@ -1033,6 +1059,7 @@ var RouteStore = class _RouteStore {
1033
1059
  };
1034
1060
 
1035
1061
  export {
1062
+ resolveUserHome,
1036
1063
  createLoopbackConnection,
1037
1064
  fixOwnership,
1038
1065
  isErrnoException,