diff --git a/src/gateway/credentials.test.ts b/src/gateway/credentials.test.ts index a3f3a8b9f45..a927395e833 100644 --- a/src/gateway/credentials.test.ts +++ b/src/gateway/credentials.test.ts @@ -71,6 +71,43 @@ function resolveLocalModeWithUnresolvedPassword(mode: "none" | "trusted-proxy") }); } +function expectUnresolvedLocalAuthSecretRefFailure(params: { + authMode: "token" | "password"; + secretId: string; + errorPath: "gateway.auth.token" | "gateway.auth.password"; + remote?: { token?: string; password?: string }; +}) { + const localAuth = + params.authMode === "token" + ? { + mode: "token" as const, + token: { source: "env", provider: "default", id: params.secretId }, + } + : { + mode: "password" as const, + password: { source: "env", provider: "default", id: params.secretId }, + }; + + expect(() => + resolveGatewayCredentialsFromConfig({ + cfg: { + gateway: { + mode: "local", + auth: localAuth, + remote: params.remote, + }, + secrets: { + providers: { + default: { source: "env" }, + }, + }, + } as unknown as OpenClawConfig, + env: {} as NodeJS.ProcessEnv, + includeLegacyEnv: false, + }), + ).toThrow(params.errorPath); +} + describe("resolveGatewayCredentialsFromConfig", () => { it("prefers explicit credentials over config and environment", () => { const resolved = resolveGatewayCredentialsFor( @@ -159,78 +196,29 @@ describe("resolveGatewayCredentialsFromConfig", () => { }); it("fails closed when local token SecretRef is unresolved and remote token fallback exists", () => { - expect(() => - resolveGatewayCredentialsFromConfig({ - cfg: { - gateway: { - mode: "local", - auth: { - mode: "token", - token: { source: "env", provider: "default", id: "MISSING_LOCAL_TOKEN" }, - }, - remote: { - token: "remote-token", - }, - }, - secrets: { - providers: { - default: { source: "env" }, - }, - }, - } as unknown as OpenClawConfig, - env: {} as NodeJS.ProcessEnv, - includeLegacyEnv: false, - }), - ).toThrow("gateway.auth.token"); + expectUnresolvedLocalAuthSecretRefFailure({ + authMode: "token", + secretId: "MISSING_LOCAL_TOKEN", + errorPath: "gateway.auth.token", + remote: { token: "remote-token" }, + }); }); it("fails closed when local password SecretRef is unresolved and remote password fallback exists", () => { - expect(() => - resolveGatewayCredentialsFromConfig({ - cfg: { - gateway: { - mode: "local", - auth: { - mode: "password", - password: { source: "env", provider: "default", id: "MISSING_LOCAL_PASSWORD" }, - }, - remote: { - password: "remote-password", // pragma: allowlist secret - }, - }, - secrets: { - providers: { - default: { source: "env" }, - }, - }, - } as unknown as OpenClawConfig, - env: {} as NodeJS.ProcessEnv, - includeLegacyEnv: false, - }), - ).toThrow("gateway.auth.password"); + expectUnresolvedLocalAuthSecretRefFailure({ + authMode: "password", + secretId: "MISSING_LOCAL_PASSWORD", + errorPath: "gateway.auth.password", + remote: { password: "remote-password" }, // pragma: allowlist secret + }); }); it("throws when local password auth relies on an unresolved SecretRef", () => { - expect(() => - resolveGatewayCredentialsFromConfig({ - cfg: { - gateway: { - mode: "local", - auth: { - mode: "password", - password: { source: "env", provider: "default", id: "MISSING_GATEWAY_PASSWORD" }, - }, - }, - secrets: { - providers: { - default: { source: "env" }, - }, - }, - } as unknown as OpenClawConfig, - env: {} as NodeJS.ProcessEnv, - includeLegacyEnv: false, - }), - ).toThrow("gateway.auth.password"); + expectUnresolvedLocalAuthSecretRefFailure({ + authMode: "password", + secretId: "MISSING_GATEWAY_PASSWORD", + errorPath: "gateway.auth.password", + }); }); it("treats env-template local tokens as SecretRefs instead of plaintext", () => { @@ -275,55 +263,21 @@ describe("resolveGatewayCredentialsFromConfig", () => { }); it("throws when unresolved local token SecretRef would otherwise fall back to remote token", () => { - expect(() => - resolveGatewayCredentialsFromConfig({ - cfg: { - gateway: { - mode: "local", - auth: { - mode: "token", - token: { source: "env", provider: "default", id: "MISSING_LOCAL_TOKEN" }, - }, - remote: { - token: "remote-token", - }, - }, - secrets: { - providers: { - default: { source: "env" }, - }, - }, - } as unknown as OpenClawConfig, - env: {} as NodeJS.ProcessEnv, - includeLegacyEnv: false, - }), - ).toThrow("gateway.auth.token"); + expectUnresolvedLocalAuthSecretRefFailure({ + authMode: "token", + secretId: "MISSING_LOCAL_TOKEN", + errorPath: "gateway.auth.token", + remote: { token: "remote-token" }, + }); }); it("throws when unresolved local password SecretRef would otherwise fall back to remote password", () => { - expect(() => - resolveGatewayCredentialsFromConfig({ - cfg: { - gateway: { - mode: "local", - auth: { - mode: "password", - password: { source: "env", provider: "default", id: "MISSING_LOCAL_PASSWORD" }, - }, - remote: { - password: "remote-password", // pragma: allowlist secret - }, - }, - secrets: { - providers: { - default: { source: "env" }, - }, - }, - } as unknown as OpenClawConfig, - env: {} as NodeJS.ProcessEnv, - includeLegacyEnv: false, - }), - ).toThrow("gateway.auth.password"); + expectUnresolvedLocalAuthSecretRefFailure({ + authMode: "password", + secretId: "MISSING_LOCAL_PASSWORD", + errorPath: "gateway.auth.password", + remote: { password: "remote-password" }, // pragma: allowlist secret + }); }); it("ignores unresolved local password ref when local auth mode is none", () => {