fix(cli): generate a UI password for bare --ui-password in daemon/serve mode
The grand tunnel restructuring removed the CLI's auto-generated UI password, so `openchamber -d --ui-password` (no value) silently started an unauthenticated server instead of creating a password as in 1.8.1. Restore generation for an explicit --ui-password flag without a value: the password is generated before either launch path, passed to the daemon/foreground process via OPENCHAMBER_UI_PASSWORD, persisted in the instance state file, and surfaced once in human/quiet/json output. Refs OPE-216
This commit is contained in:
@@ -2,7 +2,7 @@ import fs from 'fs';
|
||||
import { pathToFileURL } from 'url';
|
||||
import { spawn } from 'child_process';
|
||||
import { EXIT_CODE, TunnelCliError } from './cli-errors.js';
|
||||
import { buildLocalUrl, resolveServeHost, assertSafeBrowserPort, hasUiPasswordConfigured, assertAuthenticatedNetworkExposure } from './cli-network.js';
|
||||
import { buildLocalUrl, resolveServeHost, assertSafeBrowserPort, resolveServeUiPassword, assertAuthenticatedNetworkExposure } from './cli-network.js';
|
||||
import { fetchSystemInfoFromPort } from './cli-http.js';
|
||||
import { isPortAvailable, resolveAvailablePort } from './cli-ports.js';
|
||||
import { ensureLogsDir, getLogFilePath } from './cli-paths.js';
|
||||
@@ -110,7 +110,13 @@ async function serveCommand(options) {
|
||||
rotateLogFile(initialLogPath);
|
||||
const logFd = fs.openSync(initialLogPath, 'a');
|
||||
|
||||
const effectiveUiPassword = hasUiPasswordConfigured(options.uiPassword) ? options.uiPassword : undefined;
|
||||
// Resolve the effective UI password before either launch path so a
|
||||
// password generated for `--ui-password` (no value) is set in the
|
||||
// daemon/foreground environment before spawning and persisted in the
|
||||
// instance state file the server and restart/status flows read.
|
||||
const resolvedUiPassword = resolveServeUiPassword(options);
|
||||
const effectiveUiPassword = resolvedUiPassword.password;
|
||||
const autoGeneratedUiPassword = resolvedUiPassword.generated === true;
|
||||
assertAuthenticatedNetworkExposure({
|
||||
host: effectiveHost,
|
||||
uiPassword: effectiveUiPassword,
|
||||
@@ -214,8 +220,15 @@ async function serveCommand(options) {
|
||||
|
||||
if (isQuietMode(options)) {
|
||||
if (!options.suppressQuietOutput) {
|
||||
realStdoutWrite(`${resolvedPort}\n`);
|
||||
realStdoutWrite(
|
||||
autoGeneratedUiPassword
|
||||
? `${resolvedPort} pass:${effectiveUiPassword}\n`
|
||||
: `${resolvedPort}\n`
|
||||
);
|
||||
}
|
||||
} else if (autoGeneratedUiPassword && showOutput && !options.suppressStartupSummary) {
|
||||
console.log(`Generated UI password: ${effectiveUiPassword}`);
|
||||
console.log('Save this password — it is not shown again.');
|
||||
}
|
||||
|
||||
// Clean up PID / instance files.
|
||||
@@ -365,7 +378,11 @@ async function serveCommand(options) {
|
||||
};
|
||||
|
||||
if (isJsonMode(options)) {
|
||||
printJson({ ...serveResult, messages: jsonMessages });
|
||||
printJson({
|
||||
...serveResult,
|
||||
messages: jsonMessages,
|
||||
...(autoGeneratedUiPassword ? { password: effectiveUiPassword } : {}),
|
||||
});
|
||||
return resolvedPort;
|
||||
}
|
||||
|
||||
@@ -373,7 +390,14 @@ async function serveCommand(options) {
|
||||
if (options.suppressQuietOutput) {
|
||||
return resolvedPort;
|
||||
}
|
||||
process.stdout.write(`${resolvedPort}\n`);
|
||||
// A generated password is essential result data for scripts: include it
|
||||
// in the same compact `pass:` token form `openchamber status --quiet`
|
||||
// already emits. Configured passwords are never echoed.
|
||||
process.stdout.write(
|
||||
autoGeneratedUiPassword
|
||||
? `${resolvedPort} pass:${effectiveUiPassword}\n`
|
||||
: `${resolvedPort}\n`
|
||||
);
|
||||
return resolvedPort;
|
||||
}
|
||||
|
||||
@@ -382,6 +406,10 @@ async function serveCommand(options) {
|
||||
if (!options.suppressStartupSummary && showOutput) {
|
||||
clackIntro('OpenChamber Started');
|
||||
logStatus('success', `port ${serveResult.port} (PID: ${serveResult.pid})`);
|
||||
if (autoGeneratedUiPassword) {
|
||||
logStatus('success', 'UI password', effectiveUiPassword);
|
||||
logStatus('warning', 'save this password', 'it is not shown again');
|
||||
}
|
||||
logStatus('info', `visit: ${serveResult.url}`);
|
||||
logStatus('info', `logs: ${serveResult.logs}`);
|
||||
clackOutro('daemon running');
|
||||
|
||||
Reference in New Issue
Block a user