refactor: share gateway connection auth options

This commit is contained in:
Peter Steinberger 2026-03-14 00:23:59 +00:00
parent 42f9737e59
commit 944a2c93e3
2 changed files with 92 additions and 113 deletions

View File

@ -20,6 +20,64 @@ function cfg(input: Partial<OpenClawConfig>): OpenClawConfig {
return input as OpenClawConfig;
}
function createRemoteModeConfig() {
return {
gateway: {
mode: "remote" as const,
auth: {
token: "local-token",
password: "local-password", // pragma: allowlist secret
},
remote: {
url: "wss://remote.example",
token: "remote-token",
password: "remote-password", // pragma: allowlist secret
},
},
};
}
function createUnresolvedLocalAuthConfig(params: {
mode: "token" | "password";
id: string;
remoteFallback: string;
}) {
return cfg({
gateway: {
mode: "local",
auth: {
mode: params.mode,
[params.mode]: { source: "env", provider: "default", id: params.id },
},
remote: {
[params.mode]: params.remoteFallback,
},
},
secrets: {
providers: {
default: { source: "env" },
},
},
});
}
async function expectFailClosedOnUnresolvedLocalAuth(config: OpenClawConfig, path: string) {
await expect(
resolveGatewayConnectionAuth({
config,
env: {} as NodeJS.ProcessEnv,
includeLegacyEnv: false,
}),
).rejects.toThrow(path);
expect(() =>
resolveGatewayConnectionAuthFromConfig({
cfg: config,
env: {} as NodeJS.ProcessEnv,
includeLegacyEnv: false,
}),
).toThrow(path);
}
const DEFAULT_ENV = {
OPENCLAW_GATEWAY_TOKEN: "env-token",
OPENCLAW_GATEWAY_PASSWORD: "env-password", // pragma: allowlist secret
@ -93,20 +151,7 @@ describe("resolveGatewayConnectionAuth", () => {
},
{
name: "remote mode defaults to remote-first token and env-first password",
cfg: cfg({
gateway: {
mode: "remote",
auth: {
token: "local-token",
password: "local-password", // pragma: allowlist secret
},
remote: {
url: "wss://remote.example",
token: "remote-token",
password: "remote-password", // pragma: allowlist secret
},
},
}),
cfg: cfg(createRemoteModeConfig()),
env: DEFAULT_ENV,
expected: {
token: "remote-token",
@ -115,20 +160,7 @@ describe("resolveGatewayConnectionAuth", () => {
},
{
name: "remote mode supports env-first token with remote-first password",
cfg: cfg({
gateway: {
mode: "remote",
auth: {
token: "local-token",
password: "local-password", // pragma: allowlist secret
},
remote: {
url: "wss://remote.example",
token: "remote-token",
password: "remote-password", // pragma: allowlist secret
},
},
}),
cfg: cfg(createRemoteModeConfig()),
env: DEFAULT_ENV,
options: {
remoteTokenPrecedence: "env-first",
@ -418,72 +450,24 @@ describe("resolveGatewayConnectionAuth", () => {
});
it("fails closed when local token SecretRef is unresolved and remote token fallback exists", async () => {
const config = 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" },
},
},
});
await expect(
resolveGatewayConnectionAuth({
config,
env: {} as NodeJS.ProcessEnv,
includeLegacyEnv: false,
await expectFailClosedOnUnresolvedLocalAuth(
createUnresolvedLocalAuthConfig({
mode: "token",
id: "MISSING_LOCAL_TOKEN",
remoteFallback: "remote-token",
}),
).rejects.toThrow("gateway.auth.token");
expect(() =>
resolveGatewayConnectionAuthFromConfig({
cfg: config,
env: {} as NodeJS.ProcessEnv,
includeLegacyEnv: false,
}),
).toThrow("gateway.auth.token");
"gateway.auth.token",
);
});
it("fails closed when local password SecretRef is unresolved and remote password fallback exists", async () => {
const config = 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" },
},
},
});
await expect(
resolveGatewayConnectionAuth({
config,
env: {} as NodeJS.ProcessEnv,
includeLegacyEnv: false,
await expectFailClosedOnUnresolvedLocalAuth(
createUnresolvedLocalAuthConfig({
mode: "password",
id: "MISSING_LOCAL_PASSWORD",
remoteFallback: "remote-password", // pragma: allowlist secret
}),
).rejects.toThrow("gateway.auth.password");
expect(() =>
resolveGatewayConnectionAuthFromConfig({
cfg: config,
env: {} as NodeJS.ProcessEnv,
includeLegacyEnv: false,
}),
).toThrow("gateway.auth.password");
"gateway.auth.password",
);
});
});

View File

@ -25,30 +25,10 @@ export type GatewayConnectionAuthOptions = {
remotePasswordFallback?: GatewayRemoteCredentialFallback;
};
export async function resolveGatewayConnectionAuth(
params: GatewayConnectionAuthOptions,
): Promise<{ token?: string; password?: string }> {
return await resolveGatewayCredentialsWithSecretInputs({
config: params.config,
env: params.env,
explicitAuth: params.explicitAuth,
urlOverride: params.urlOverride,
urlOverrideSource: params.urlOverrideSource,
modeOverride: params.modeOverride,
includeLegacyEnv: params.includeLegacyEnv,
localTokenPrecedence: params.localTokenPrecedence,
localPasswordPrecedence: params.localPasswordPrecedence,
remoteTokenPrecedence: params.remoteTokenPrecedence,
remotePasswordPrecedence: params.remotePasswordPrecedence,
remoteTokenFallback: params.remoteTokenFallback,
remotePasswordFallback: params.remotePasswordFallback,
});
}
export function resolveGatewayConnectionAuthFromConfig(
function toGatewayCredentialOptions(
params: Omit<GatewayConnectionAuthOptions, "config"> & { cfg: OpenClawConfig },
): { token?: string; password?: string } {
return resolveGatewayCredentialsFromConfig({
) {
return {
cfg: params.cfg,
env: params.env,
explicitAuth: params.explicitAuth,
@ -62,5 +42,20 @@ export function resolveGatewayConnectionAuthFromConfig(
remotePasswordPrecedence: params.remotePasswordPrecedence,
remoteTokenFallback: params.remoteTokenFallback,
remotePasswordFallback: params.remotePasswordFallback,
};
}
export async function resolveGatewayConnectionAuth(
params: GatewayConnectionAuthOptions,
): Promise<{ token?: string; password?: string }> {
return await resolveGatewayCredentialsWithSecretInputs({
config: params.config,
...toGatewayCredentialOptions({ ...params, cfg: params.config }),
});
}
export function resolveGatewayConnectionAuthFromConfig(
params: Omit<GatewayConnectionAuthOptions, "config"> & { cfg: OpenClawConfig },
): { token?: string; password?: string } {
return resolveGatewayCredentialsFromConfig(toGatewayCredentialOptions(params));
}