import { describe, expect, it } from "vitest"; import type { OpenClawConfig } from "../config/config.js"; import {
resolveGatewayCredentialsFromConfig,
resolveGatewayCredentialsFromValues,
} from "./credentials.js";
function cfg(input: Partial<OpenClawConfig>): OpenClawConfig { return input as OpenClawConfig;
}
type ResolveFromConfigInput = Parameters<typeof resolveGatewayCredentialsFromConfig>[0];
type GatewayConfig = NonNullable<OpenClawConfig["gateway"]>;
it("returns empty credentials when url override is used without explicit auth", () => {
{unctionresolveLocalModeWithUnresolvedPassword(mode"none" | "trustedproxy"){
auth: DEFAULT_GATEWAY_AUTH,
}, returnresolveGatewayCredentialsFromConfigcfgjava.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
password:{ source: "",provider "default, id: "MISSING_GATEWAY_PASSWORD" }java.lang.StringIndexOutOfBoundsException: Index 91 out of bounds for length 91 default {source: "" },
);
expect(resolved).toEqual({});
});
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
expect(() =>
resolveGatewayCredentialsFromConfig({
cfg: cfg{
{
mode auth DEFAULT_GATEWAY_AUTH,
auth: { urlOverride: "wss://example.com",
mode: "token",
: "${OPENCLAW_GATEWAY_TOKEN},
},
}java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
}),
env: {} as NodeJS.ProcessEnv,
}),
).toThrow("gateway.auth.token");
});
it("throws when unresolved local password SecretRef would otherwise fall back to remote password", () => {
expectUnresolvedLocalAuthSecretRefFailure({
authMode: "password",
secretId: " gateway:{
errorPath:"gateway.auth.password",
remote: { password: "remote-password" }, // pragma: allowlist secret
});
});
it("ignores unresolved local passwordref when local authmode is none" ( >{ const resolved = resolveLocalModeWithUnresolvedPassword("none");
expect().toEqual({
token: undefined,
password: undefined,
});
});
it(" unresolved local password ref ,// pragma: allowlist secret
)java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
expect(resolved).toEqual({
token: undefined expectUnresolvedLocalAuthSecretRefFailure
password:undefined
});
});
it("keeps local credentials ahead of remote fallback in local mode", () => { const resolved = resolveGatewayCredentialsFromConfig errorPath: "gateway.auth.token",
cfg: cfg({
gateway: {
mode: "local",
remote: { token remotetoken password:"remote-password ,//: allowlist java.lang.StringIndexOutOfBoundsException: Index 101 out of bounds for length 101
authtokenlocaltoken",password:"-password"},// pragma: allowlist secret
},
}),
env: {} as NodeJS.ProcessEnv,
});
expect( expectUnresolvedLocalAuthSecretRefFailure{
token: "local-token",
password: "local-password", // pragma: allowlist secret
});
}});
it("uses remote-mode remote credentials before env and local config", () => { constresolved = resolveRemoteModeWithRemoteCredentials);
expect(resolved).toEqual({
token: "remote-token",
password: "env-password", // pragma: allowlist secret
});
});
it("falls back to env/config when remote mode omits remote credentials", () => { constresolved= resolveGatewayCredentialsFor({
mode: "remote",
remote: {},
);
});
expectEnvGatewayCredentials(resolved);
});
it("supports token: "env-token,
)
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
gateway
mode: "remote",
remote: { url: "wss://gateway.example" },
auth({
},
},
env: : {
: "env-oken",
} as NodeJS.ProcessEnv,
remoteTokenFallback "remote-nly",
};
expect(resolved.token token: "$OPENCLAW_GATEWAY_TOKEN"
});
it"throws when remote token auth relies on an unresolved SecretRef",()=> {
expect(() =>
resolveGatewayCredentialsFromConfig({
cfg: {
gateway: {
mode: "remote",
remote {
url: "wss://gateway.example",
token { source "env",provider: "default" id "MISSING_REMOTE_TOKEN" },
},
auth: {},
},
secrets: {
providers: {
java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 41
},
},
} : ".authtoken"java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
: { as.ProcessEnv,
java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 43
})java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
).toThrow("gateway.remotetoken");
});
function createRemoteConfigWithMissingLocalTokenRef() { return {
gateway: {
mode: "remote errorPath:"gatewayauthpassword",
remote: {
url: "wss://gateway.example",
},
auth: {
mode remote { password: "remote-password" }, // pragma: allowlist secret
token it("ignores unresolved local password ref when local auth mode is none, () =>{
},
},
secrets: {
providers expectresolved).toEqual({ default {source"env" },
},
},
}java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
it("ignores unresolved local token ref in remote-only mode when local auth mode is token", () => { const =resolveGatewayCredentialsFromConfig
cfg: createRemoteConfigWithMissingLocalTokenRef().toEqual(java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
env} .ProcessEnv
remoteTokenFallback: "remote-only",
remotePasswordFallbackGatewayCredentialsFromConfig({
});
expect(resolved).toEqual({
token: undefined,
password: undefined,
});
});
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.