* fix(cli): honor PASEO_PASSWORD env var (fix #776) The CLI only extracted passwords from `tcp://host?password=` URIs, so `PASEO_PASSWORD=xxxx paseo ls` connected without auth and was rejected by the daemon with "Password required". Fall back to the env var when the host (TCP or otherwise) carries no password. * docs: document PASEO_PASSWORD env var as a CLI auth source Pairs with the CLI fix in this branch — the "Connecting with a password" section now lists both the tcp URI query and the env-var fallback, with their precedence. Also clarify the dual role (daemon vs CLI) of PASEO_PASSWORD in the env var reference.
This commit is contained in:
@@ -218,7 +218,12 @@ export function resolveDaemonTarget(host: string): DaemonTarget {
|
|||||||
|
|
||||||
export function resolveDaemonPassword(host: string): string | undefined {
|
export function resolveDaemonPassword(host: string): string | undefined {
|
||||||
const trimmed = host.trim();
|
const trimmed = host.trim();
|
||||||
return trimmed.startsWith("tcp://") ? parseConnectionUri(trimmed).password : undefined;
|
if (trimmed.startsWith("tcp://")) {
|
||||||
|
const fromUri = parseConnectionUri(trimmed).password;
|
||||||
|
if (fromUri) return fromUri;
|
||||||
|
}
|
||||||
|
const fromEnv = process.env.PASEO_PASSWORD;
|
||||||
|
return fromEnv && fromEnv.length > 0 ? fromEnv : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -143,14 +143,49 @@ console.log("=== CLI IPC Target Helpers ===\n");
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
console.log("Test 10: daemon password resolution uses only the TCP URI query");
|
console.log("Test 10: daemon password resolution prefers TCP URI query, falls back to env");
|
||||||
assert.strictEqual(
|
const previousEnv = process.env.PASEO_PASSWORD;
|
||||||
resolveDaemonPassword("tcp://example.com:6767?ssl=true&password=query-secret"),
|
try {
|
||||||
"query-secret",
|
delete process.env.PASEO_PASSWORD;
|
||||||
);
|
assert.strictEqual(
|
||||||
assert.strictEqual(resolveDaemonPassword("tcp://missing.example:6767"), undefined);
|
resolveDaemonPassword("tcp://example.com:6767?ssl=true&password=query-secret"),
|
||||||
assert.strictEqual(resolveDaemonPassword("example.com:6767"), undefined);
|
"query-secret",
|
||||||
console.log("✓ daemon password resolution uses only the TCP URI query\n");
|
);
|
||||||
|
assert.strictEqual(resolveDaemonPassword("tcp://missing.example:6767"), undefined);
|
||||||
|
assert.strictEqual(resolveDaemonPassword("example.com:6767"), undefined);
|
||||||
|
|
||||||
|
process.env.PASEO_PASSWORD = "env-secret";
|
||||||
|
assert.strictEqual(
|
||||||
|
resolveDaemonPassword("tcp://example.com:6767?ssl=true&password=query-secret"),
|
||||||
|
"query-secret",
|
||||||
|
"URI password should take precedence over env var",
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
resolveDaemonPassword("tcp://missing.example:6767"),
|
||||||
|
"env-secret",
|
||||||
|
"TCP host without query password should fall back to env var",
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
resolveDaemonPassword("example.com:6767"),
|
||||||
|
"env-secret",
|
||||||
|
"Bare host should pick up env var password",
|
||||||
|
);
|
||||||
|
assert.strictEqual(resolveDaemonPassword("localhost:6767"), "env-secret");
|
||||||
|
|
||||||
|
process.env.PASEO_PASSWORD = "";
|
||||||
|
assert.strictEqual(
|
||||||
|
resolveDaemonPassword("localhost:6767"),
|
||||||
|
undefined,
|
||||||
|
"Empty env var should be treated as unset",
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
if (previousEnv === undefined) {
|
||||||
|
delete process.env.PASEO_PASSWORD;
|
||||||
|
} else {
|
||||||
|
process.env.PASEO_PASSWORD = previousEnv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("✓ daemon password resolution prefers TCP URI query, falls back to env\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("=== All CLI IPC target tests passed ===");
|
console.log("=== All CLI IPC target tests passed ===");
|
||||||
|
|||||||
@@ -123,18 +123,29 @@ After setting a password, restart the daemon for the change to take effect.
|
|||||||
|
|
||||||
### Connecting with a password
|
### Connecting with a password
|
||||||
|
|
||||||
The CLI reads the password from the TCP URI automatically:
|
The CLI picks up a password from, in order:
|
||||||
|
|
||||||
```bash
|
1. The `password` query parameter on a `tcp://` host URI:
|
||||||
paseo --host "tcp://192.168.1.10:6767?password=my-secret" ls
|
|
||||||
```
|
```bash
|
||||||
|
paseo --host "tcp://192.168.1.10:6767?password=my-secret" ls
|
||||||
|
```
|
||||||
|
|
||||||
|
2. The `PASEO_PASSWORD` environment variable, used as a fallback when the host carries no embedded password (works for `localhost:6767`, bare `host:port`, or `tcp://` hosts without a `password=` query):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
PASEO_PASSWORD=my-secret paseo ls
|
||||||
|
PASEO_PASSWORD=my-secret paseo --host 192.168.1.10:6767 ls
|
||||||
|
```
|
||||||
|
|
||||||
|
A `password=` in the URI always wins over the env var, so you can keep `PASEO_PASSWORD` set globally and still target a different daemon by spelling its password into the URI.
|
||||||
|
|
||||||
In the mobile app, enter the password in the direct connection setup screen.
|
In the mobile app, enter the password in the direct connection setup screen.
|
||||||
|
|
||||||
## Common env vars
|
## Common env vars
|
||||||
|
|
||||||
- `PASEO_HOME` — set Paseo home directory
|
- `PASEO_HOME` — set Paseo home directory
|
||||||
- `PASEO_PASSWORD` — require a password to connect (plaintext, hashed at startup)
|
- `PASEO_PASSWORD` — on the daemon, the password to require (plaintext, hashed at startup); on the CLI, the password used to connect when the host URI doesn't include one
|
||||||
- `PASEO_LISTEN` — override `daemon.listen`
|
- `PASEO_LISTEN` — override `daemon.listen`
|
||||||
- `PASEO_HOSTNAMES` — override/extend `daemon.hostnames`
|
- `PASEO_HOSTNAMES` — override/extend `daemon.hostnames`
|
||||||
- `PASEO_ALLOWED_HOSTS` — deprecated alias for `PASEO_HOSTNAMES`
|
- `PASEO_ALLOWED_HOSTS` — deprecated alias for `PASEO_HOSTNAMES`
|
||||||
|
|||||||
Reference in New Issue
Block a user