mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 13:40:44 +00:00
fix: preserve setup-entry secrets
This commit is contained in:
@@ -523,6 +523,7 @@ function createSetupEntryChannelPluginFixture(params: {
|
||||
configured: boolean;
|
||||
startupDeferConfiguredChannelFullLoadUntilAfterListen?: boolean;
|
||||
useBundledSetupEntryContract?: boolean;
|
||||
splitBundledSetupSecrets?: boolean;
|
||||
}) {
|
||||
useNoBundledPlugins();
|
||||
const pluginDir = makeTempDir();
|
||||
@@ -618,6 +619,18 @@ module.exports = {
|
||||
},
|
||||
outbound: { deliveryMode: "direct" },
|
||||
}),
|
||||
${
|
||||
params.splitBundledSetupSecrets
|
||||
? `loadSetupSecrets: () => ({
|
||||
secretTargetRegistryEntries: [
|
||||
{
|
||||
id: ${JSON.stringify(`channels.${params.id}.setup-token`)},
|
||||
targetType: "channel",
|
||||
},
|
||||
],
|
||||
}),`
|
||||
: ""
|
||||
}
|
||||
};`
|
||||
: `require("node:fs").writeFileSync(${JSON.stringify(setupMarker)}, "loaded", "utf-8");
|
||||
module.exports = {
|
||||
@@ -3215,6 +3228,33 @@ module.exports = {
|
||||
expectSetupLoaded: true,
|
||||
expectedChannels: 1,
|
||||
},
|
||||
{
|
||||
name: "preserves bundled setupEntry split secrets for setup-runtime channel loads",
|
||||
fixture: {
|
||||
id: "setup-runtime-bundled-contract-secrets-test",
|
||||
label: "Setup Runtime Bundled Contract Secrets Test",
|
||||
packageName: "@openclaw/setup-runtime-bundled-contract-secrets-test",
|
||||
fullBlurb: "full entry should not run while unconfigured",
|
||||
setupBlurb: "setup runtime bundled contract secrets",
|
||||
configured: false,
|
||||
useBundledSetupEntryContract: true,
|
||||
splitBundledSetupSecrets: true,
|
||||
},
|
||||
load: ({ pluginDir }: { pluginDir: string }) =>
|
||||
loadOpenClawPlugins({
|
||||
cache: false,
|
||||
config: {
|
||||
plugins: {
|
||||
load: { paths: [pluginDir] },
|
||||
allow: ["setup-runtime-bundled-contract-secrets-test"],
|
||||
},
|
||||
},
|
||||
}),
|
||||
expectFullLoaded: false,
|
||||
expectSetupLoaded: true,
|
||||
expectedChannels: 1,
|
||||
expectedSetupSecretId: "channels.setup-runtime-bundled-contract-secrets-test.setup-token",
|
||||
},
|
||||
{
|
||||
name: "does not prefer setupEntry for configured channel loads without startup opt-in",
|
||||
fixture: {
|
||||
@@ -3246,15 +3286,41 @@ module.exports = {
|
||||
expectSetupLoaded: false,
|
||||
expectedChannels: 1,
|
||||
},
|
||||
])("$name", ({ fixture, load, expectFullLoaded, expectSetupLoaded, expectedChannels }) => {
|
||||
const built = createSetupEntryChannelPluginFixture(fixture);
|
||||
const registry = load({ pluginDir: built.pluginDir });
|
||||
])(
|
||||
"$name",
|
||||
({
|
||||
fixture,
|
||||
load,
|
||||
expectFullLoaded,
|
||||
expectSetupLoaded,
|
||||
expectedChannels,
|
||||
expectedSetupSecretId,
|
||||
}) => {
|
||||
const built = createSetupEntryChannelPluginFixture(fixture);
|
||||
const registry = load({ pluginDir: built.pluginDir });
|
||||
|
||||
expect(fs.existsSync(built.fullMarker)).toBe(expectFullLoaded);
|
||||
expect(fs.existsSync(built.setupMarker)).toBe(expectSetupLoaded);
|
||||
expect(registry.channelSetups).toHaveLength(1);
|
||||
expect(registry.channels).toHaveLength(expectedChannels);
|
||||
});
|
||||
expect(fs.existsSync(built.fullMarker)).toBe(expectFullLoaded);
|
||||
expect(fs.existsSync(built.setupMarker)).toBe(expectSetupLoaded);
|
||||
expect(registry.channelSetups).toHaveLength(1);
|
||||
expect(registry.channels).toHaveLength(expectedChannels);
|
||||
if (expectedSetupSecretId) {
|
||||
expect(registry.channelSetups[0]?.plugin.secrets?.secretTargetRegistryEntries).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: expectedSetupSecretId,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
expect(registry.channels[0]?.plugin.secrets?.secretTargetRegistryEntries).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: expectedSetupSecretId,
|
||||
}),
|
||||
]),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
it("isolates loadSetupPlugin errors as per-plugin diagnostics instead of crashing registry load", () => {
|
||||
useNoBundledPlugins();
|
||||
|
||||
@@ -644,6 +644,26 @@ function resolvePluginModuleExport(moduleExport: unknown): {
|
||||
return {};
|
||||
}
|
||||
|
||||
function mergeSetupPluginSection<T>(
|
||||
baseValue: T | undefined,
|
||||
setupValue: T | undefined,
|
||||
): T | undefined {
|
||||
if (baseValue && setupValue && typeof baseValue === "object" && typeof setupValue === "object") {
|
||||
const merged = {
|
||||
...(baseValue as Record<string, unknown>),
|
||||
};
|
||||
for (const [key, value] of Object.entries(setupValue as Record<string, unknown>)) {
|
||||
if (value !== undefined) {
|
||||
merged[key] = value;
|
||||
}
|
||||
}
|
||||
return {
|
||||
...merged,
|
||||
} as T;
|
||||
}
|
||||
return setupValue ?? baseValue;
|
||||
}
|
||||
|
||||
function resolveSetupChannelRegistration(moduleExport: unknown): {
|
||||
plugin?: ChannelPlugin;
|
||||
loadError?: unknown;
|
||||
@@ -655,6 +675,7 @@ function resolveSetupChannelRegistration(moduleExport: unknown): {
|
||||
const setupEntryRecord = resolved as {
|
||||
kind?: unknown;
|
||||
loadSetupPlugin?: unknown;
|
||||
loadSetupSecrets?: unknown;
|
||||
};
|
||||
if (
|
||||
setupEntryRecord.kind === "bundled-channel-setup-entry" &&
|
||||
@@ -662,9 +683,20 @@ function resolveSetupChannelRegistration(moduleExport: unknown): {
|
||||
) {
|
||||
try {
|
||||
const loadedPlugin = setupEntryRecord.loadSetupPlugin();
|
||||
const loadedSecrets =
|
||||
typeof setupEntryRecord.loadSetupSecrets === "function"
|
||||
? (setupEntryRecord.loadSetupSecrets() as ChannelPlugin["secrets"] | undefined)
|
||||
: undefined;
|
||||
if (loadedPlugin && typeof loadedPlugin === "object") {
|
||||
const mergedSecrets = mergeSetupPluginSection(
|
||||
(loadedPlugin as ChannelPlugin).secrets,
|
||||
loadedSecrets,
|
||||
);
|
||||
return {
|
||||
plugin: loadedPlugin as ChannelPlugin,
|
||||
plugin: {
|
||||
...(loadedPlugin as ChannelPlugin),
|
||||
...(mergedSecrets !== undefined ? { secrets: mergedSecrets } : {}),
|
||||
},
|
||||
};
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
Reference in New Issue
Block a user