mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 22:41:36 +00:00
fix: Finish credential redaction that was merged unfinished (#13073)
* Squash * Removed unused files Not mine, someone merged that stuff in earlier. * fix: patch redaction regressions and schema breakages --------- Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
@@ -17,7 +17,7 @@ import {
|
||||
redactConfigSnapshot,
|
||||
restoreRedactedValues,
|
||||
} from "../../config/redact-snapshot.js";
|
||||
import { buildConfigSchema } from "../../config/schema.js";
|
||||
import { buildConfigSchema, type ConfigSchemaResponse } from "../../config/schema.js";
|
||||
import {
|
||||
formatDoctorNonInteractiveHint,
|
||||
type RestartSentinelPayload,
|
||||
@@ -91,6 +91,41 @@ function requireConfigBaseHash(
|
||||
return true;
|
||||
}
|
||||
|
||||
function loadSchemaWithPlugins(): ConfigSchemaResponse {
|
||||
const cfg = loadConfig();
|
||||
const workspaceDir = resolveAgentWorkspaceDir(cfg, resolveDefaultAgentId(cfg));
|
||||
const pluginRegistry = loadOpenClawPlugins({
|
||||
config: cfg,
|
||||
cache: true,
|
||||
workspaceDir,
|
||||
logger: {
|
||||
info: () => {},
|
||||
warn: () => {},
|
||||
error: () => {},
|
||||
debug: () => {},
|
||||
},
|
||||
});
|
||||
// Note: We can't easily cache this, as there are no callback that can invalidate
|
||||
// our cache. However, both loadConfig() and loadOpenClawPlugins() already cache
|
||||
// their results, and buildConfigSchema() is just a cheap transformation.
|
||||
return buildConfigSchema({
|
||||
plugins: pluginRegistry.plugins.map((plugin) => ({
|
||||
id: plugin.id,
|
||||
name: plugin.name,
|
||||
description: plugin.description,
|
||||
configUiHints: plugin.configUiHints,
|
||||
configSchema: plugin.configJsonSchema,
|
||||
})),
|
||||
channels: listChannelPlugins().map((entry) => ({
|
||||
id: entry.id,
|
||||
label: entry.meta.label,
|
||||
description: entry.meta.blurb,
|
||||
configSchema: entry.configSchema?.schema,
|
||||
configUiHints: entry.configSchema?.uiHints,
|
||||
})),
|
||||
});
|
||||
}
|
||||
|
||||
export const configHandlers: GatewayRequestHandlers = {
|
||||
"config.get": async ({ params, respond }) => {
|
||||
if (!validateConfigGetParams(params)) {
|
||||
@@ -105,7 +140,8 @@ export const configHandlers: GatewayRequestHandlers = {
|
||||
return;
|
||||
}
|
||||
const snapshot = await readConfigFileSnapshot();
|
||||
respond(true, redactConfigSnapshot(snapshot), undefined);
|
||||
const schema = loadSchemaWithPlugins();
|
||||
respond(true, redactConfigSnapshot(snapshot, schema.uiHints), undefined);
|
||||
},
|
||||
"config.schema": ({ params, respond }) => {
|
||||
if (!validateConfigSchemaParams(params)) {
|
||||
@@ -119,35 +155,7 @@ export const configHandlers: GatewayRequestHandlers = {
|
||||
);
|
||||
return;
|
||||
}
|
||||
const cfg = loadConfig();
|
||||
const workspaceDir = resolveAgentWorkspaceDir(cfg, resolveDefaultAgentId(cfg));
|
||||
const pluginRegistry = loadOpenClawPlugins({
|
||||
config: cfg,
|
||||
workspaceDir,
|
||||
logger: {
|
||||
info: () => {},
|
||||
warn: () => {},
|
||||
error: () => {},
|
||||
debug: () => {},
|
||||
},
|
||||
});
|
||||
const schema = buildConfigSchema({
|
||||
plugins: pluginRegistry.plugins.map((plugin) => ({
|
||||
id: plugin.id,
|
||||
name: plugin.name,
|
||||
description: plugin.description,
|
||||
configUiHints: plugin.configUiHints,
|
||||
configSchema: plugin.configJsonSchema,
|
||||
})),
|
||||
channels: listChannelPlugins().map((entry) => ({
|
||||
id: entry.id,
|
||||
label: entry.meta.label,
|
||||
description: entry.meta.blurb,
|
||||
configSchema: entry.configSchema?.schema,
|
||||
configUiHints: entry.configSchema?.uiHints,
|
||||
})),
|
||||
});
|
||||
respond(true, schema, undefined);
|
||||
respond(true, loadSchemaWithPlugins(), undefined);
|
||||
},
|
||||
"config.set": async ({ params, respond }) => {
|
||||
if (!validateConfigSetParams(params)) {
|
||||
@@ -179,7 +187,17 @@ export const configHandlers: GatewayRequestHandlers = {
|
||||
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, parsedRes.error));
|
||||
return;
|
||||
}
|
||||
const validated = validateConfigObjectWithPlugins(parsedRes.parsed);
|
||||
const schemaSet = loadSchemaWithPlugins();
|
||||
const restored = restoreRedactedValues(parsedRes.parsed, snapshot.config, schemaSet.uiHints);
|
||||
if (!restored.ok) {
|
||||
respond(
|
||||
false,
|
||||
undefined,
|
||||
errorShape(ErrorCodes.INVALID_REQUEST, restored.humanReadableMessage ?? "invalid config"),
|
||||
);
|
||||
return;
|
||||
}
|
||||
const validated = validateConfigObjectWithPlugins(restored.result);
|
||||
if (!validated.ok) {
|
||||
respond(
|
||||
false,
|
||||
@@ -190,27 +208,13 @@ export const configHandlers: GatewayRequestHandlers = {
|
||||
);
|
||||
return;
|
||||
}
|
||||
let restored: typeof validated.config;
|
||||
try {
|
||||
restored = restoreRedactedValues(
|
||||
validated.config,
|
||||
snapshot.config,
|
||||
) as typeof validated.config;
|
||||
} catch (err) {
|
||||
respond(
|
||||
false,
|
||||
undefined,
|
||||
errorShape(ErrorCodes.INVALID_REQUEST, String(err instanceof Error ? err.message : err)),
|
||||
);
|
||||
return;
|
||||
}
|
||||
await writeConfigFile(restored);
|
||||
await writeConfigFile(validated.config);
|
||||
respond(
|
||||
true,
|
||||
{
|
||||
ok: true,
|
||||
path: CONFIG_PATH,
|
||||
config: redactConfigObject(restored),
|
||||
config: redactConfigObject(validated.config, schemaSet.uiHints),
|
||||
},
|
||||
undefined,
|
||||
);
|
||||
@@ -269,19 +273,21 @@ export const configHandlers: GatewayRequestHandlers = {
|
||||
return;
|
||||
}
|
||||
const merged = applyMergePatch(snapshot.config, parsedRes.parsed);
|
||||
let restoredMerge: unknown;
|
||||
try {
|
||||
restoredMerge = restoreRedactedValues(merged, snapshot.config);
|
||||
} catch (err) {
|
||||
const schemaPatch = loadSchemaWithPlugins();
|
||||
const restoredMerge = restoreRedactedValues(merged, snapshot.config, schemaPatch.uiHints);
|
||||
if (!restoredMerge.ok) {
|
||||
respond(
|
||||
false,
|
||||
undefined,
|
||||
errorShape(ErrorCodes.INVALID_REQUEST, String(err instanceof Error ? err.message : err)),
|
||||
errorShape(
|
||||
ErrorCodes.INVALID_REQUEST,
|
||||
restoredMerge.humanReadableMessage ?? "invalid config",
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
const migrated = applyLegacyMigrations(restoredMerge);
|
||||
const resolved = migrated.next ?? restoredMerge;
|
||||
const migrated = applyLegacyMigrations(restoredMerge.result);
|
||||
const resolved = migrated.next ?? restoredMerge.result;
|
||||
const validated = validateConfigObjectWithPlugins(resolved);
|
||||
if (!validated.ok) {
|
||||
respond(
|
||||
@@ -336,7 +342,7 @@ export const configHandlers: GatewayRequestHandlers = {
|
||||
{
|
||||
ok: true,
|
||||
path: CONFIG_PATH,
|
||||
config: redactConfigObject(validated.config),
|
||||
config: redactConfigObject(validated.config, schemaPatch.uiHints),
|
||||
restart,
|
||||
sentinel: {
|
||||
path: sentinelPath,
|
||||
@@ -379,7 +385,17 @@ export const configHandlers: GatewayRequestHandlers = {
|
||||
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, parsedRes.error));
|
||||
return;
|
||||
}
|
||||
const validated = validateConfigObjectWithPlugins(parsedRes.parsed);
|
||||
const schemaApply = loadSchemaWithPlugins();
|
||||
const restored = restoreRedactedValues(parsedRes.parsed, snapshot.config, schemaApply.uiHints);
|
||||
if (!restored.ok) {
|
||||
respond(
|
||||
false,
|
||||
undefined,
|
||||
errorShape(ErrorCodes.INVALID_REQUEST, restored.humanReadableMessage ?? "invalid config"),
|
||||
);
|
||||
return;
|
||||
}
|
||||
const validated = validateConfigObjectWithPlugins(restored.result);
|
||||
if (!validated.ok) {
|
||||
respond(
|
||||
false,
|
||||
@@ -390,21 +406,7 @@ export const configHandlers: GatewayRequestHandlers = {
|
||||
);
|
||||
return;
|
||||
}
|
||||
let restoredApply: typeof validated.config;
|
||||
try {
|
||||
restoredApply = restoreRedactedValues(
|
||||
validated.config,
|
||||
snapshot.config,
|
||||
) as typeof validated.config;
|
||||
} catch (err) {
|
||||
respond(
|
||||
false,
|
||||
undefined,
|
||||
errorShape(ErrorCodes.INVALID_REQUEST, String(err instanceof Error ? err.message : err)),
|
||||
);
|
||||
return;
|
||||
}
|
||||
await writeConfigFile(restoredApply);
|
||||
await writeConfigFile(validated.config);
|
||||
|
||||
const sessionKey =
|
||||
typeof (params as { sessionKey?: unknown }).sessionKey === "string"
|
||||
@@ -447,7 +449,7 @@ export const configHandlers: GatewayRequestHandlers = {
|
||||
{
|
||||
ok: true,
|
||||
path: CONFIG_PATH,
|
||||
config: redactConfigObject(restoredApply),
|
||||
config: redactConfigObject(validated.config, schemaApply.uiHints),
|
||||
restart,
|
||||
sentinel: {
|
||||
path: sentinelPath,
|
||||
|
||||
Reference in New Issue
Block a user