mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-28 05:16:23 -06:00
fix: make gateway token recovery usable from macOS onboarding (#118051)
* fix(gateway): add safe token recovery Co-authored-by: 宇宙熊Yzx <53250620+849261680@users.noreply.github.com> * chore: move gateway release note to PR * test(cli): classify gateway token output --------- Co-authored-by: 宇宙熊Yzx <53250620+849261680@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
e47f9ba075
commit
ad53d4419e
@@ -10,6 +10,7 @@ const mocks = vi.hoisted(() => ({
|
||||
emitReachableGatewayAuthDiagnostic: vi.fn(async (_params: unknown) => false),
|
||||
formatHealthChannelLines: vi.fn(() => []),
|
||||
gatewayStatusCommand: vi.fn(async (_opts: unknown, _runtime: unknown) => {}),
|
||||
gatewayAuthTokenCommand: vi.fn(async (_runtime: unknown) => {}),
|
||||
defaultRuntime: {
|
||||
log: vi.fn(),
|
||||
error: vi.fn(),
|
||||
@@ -46,6 +47,10 @@ vi.mock("../../commands/gateway-status.js", () => ({
|
||||
mocks.gatewayStatusCommand(opts, runtime),
|
||||
}));
|
||||
|
||||
vi.mock("../../commands/gateway-auth-token.js", () => ({
|
||||
gatewayAuthTokenCommand: (runtime: unknown) => mocks.gatewayAuthTokenCommand(runtime),
|
||||
}));
|
||||
|
||||
vi.mock("../gateway-rpc.js", async () => ({
|
||||
...(await vi.importActual<typeof import("../gateway-rpc.js")>("../gateway-rpc.js")),
|
||||
callGatewayFromCliWithTransport: (method: string, opts: unknown, params?: unknown) =>
|
||||
@@ -143,6 +148,7 @@ describe("gateway register option collisions", () => {
|
||||
emitReachableGatewayAuthDiagnostic.mockClear();
|
||||
mocks.formatHealthChannelLines.mockClear();
|
||||
gatewayStatusCommand.mockClear();
|
||||
mocks.gatewayAuthTokenCommand.mockClear();
|
||||
defaultRuntime.log.mockClear();
|
||||
defaultRuntime.error.mockClear();
|
||||
defaultRuntime.writeStdout.mockClear();
|
||||
@@ -150,6 +156,23 @@ describe("gateway register option collisions", () => {
|
||||
defaultRuntime.exit.mockClear();
|
||||
});
|
||||
|
||||
it("requires explicit confirmation before revealing the Gateway token", async () => {
|
||||
await sharedProgram.parseAsync(["gateway", "auth-token"], { from: "user" });
|
||||
|
||||
expect(mocks.gatewayAuthTokenCommand).not.toHaveBeenCalled();
|
||||
expect(defaultRuntime.error).toHaveBeenCalledWith(
|
||||
expect.stringContaining("Pass --show to confirm"),
|
||||
);
|
||||
expect(defaultRuntime.exit).toHaveBeenCalledWith(1);
|
||||
});
|
||||
|
||||
it("routes an explicitly confirmed token reveal through the output runtime", async () => {
|
||||
await sharedProgram.parseAsync(["gateway", "auth-token", "--show"], { from: "user" });
|
||||
|
||||
expect(mocks.gatewayAuthTokenCommand).toHaveBeenCalledWith(defaultRuntime);
|
||||
expect(defaultRuntime.error).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it.each([
|
||||
{
|
||||
name: "forwards --token to gateway call when parent and child option names collide",
|
||||
|
||||
@@ -532,6 +532,7 @@ export function registerGatewayCli(program: Command, deps: GatewayCliDependencie
|
||||
`\n${theme.heading("Examples:")}\n${formatHelpExamples([
|
||||
["openclaw gateway run", "Run the gateway in the foreground."],
|
||||
["openclaw gateway status", "Show service status plus connectivity/capability."],
|
||||
["openclaw gateway auth-token --show", "Reveal the shared token interactively."],
|
||||
["openclaw gateway discover", "Find local and wide-area gateway beacons."],
|
||||
["openclaw gateway stability", "Show recent stability diagnostics."],
|
||||
["openclaw gateway call health", "Call a gateway RPC method directly."],
|
||||
@@ -549,6 +550,22 @@ export function registerGatewayCli(program: Command, deps: GatewayCliDependencie
|
||||
addGatewayRestartHandoffCommands(gateway);
|
||||
setCommandJsonMode(gateway, "output", ({ argv }) => isGatewayMachineOutput(argv));
|
||||
|
||||
gateway
|
||||
.command("auth-token")
|
||||
.description("Reveal the configured shared Gateway token")
|
||||
.option("--show", "Print the token to an interactive terminal", false)
|
||||
.action(async (opts) => {
|
||||
await runGatewayCommand(async () => {
|
||||
if (!opts.show) {
|
||||
throw new Error(
|
||||
"Pass --show to confirm that you want to print the Gateway token to this terminal.",
|
||||
);
|
||||
}
|
||||
const { gatewayAuthTokenCommand } = await import("../../commands/gateway-auth-token.js");
|
||||
await gatewayAuthTokenCommand(defaultRuntime);
|
||||
}, "Gateway auth token failed");
|
||||
});
|
||||
|
||||
gatewayCallOpts(
|
||||
gateway
|
||||
.command("call")
|
||||
|
||||
Reference in New Issue
Block a user