mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-22 06:32:00 +00:00
fix: preserve allowlist guard for auto-enabled bundled channels (#60233) (thanks @dorukardahan)
This commit is contained in:
@@ -64,6 +64,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Agents/tool policy: stop `tools.profile` warnings from flagging runtime-gated baseline core tools as unknown when the coding profile is missing tools like `code_execution`, `x_search`, `image`, or `image_generate`, while still warning on explicit extra allowlist entries. Thanks @vincentkoc.
|
||||
- Sessions/resolution: collapse alias-duplicate session-id matches before scoring, keep distinct structural ties ambiguous, and prefer current-store reuse when resolving equal cross-store duplicates so follow-up turns stop dropping or duplicating sessions on timestamp ties.
|
||||
- Mobile pairing/bootstrap: keep setup bootstrap tokens alive through the initial node auto-pair so the same QR bootstrap token can finish operator approval, then revoke it after the full issued profile connects successfully. (#60221) Thanks @obviyus.
|
||||
- Plugins/allowlists: let explicit bundled chat channel enablement bypass `plugins.allow`, while keeping auto-enabled channel activation and startup sidecars behind restrictive allowlists. (#60233) Thanks @dorukardahan.
|
||||
|
||||
## 2026.4.2
|
||||
|
||||
|
||||
@@ -252,6 +252,7 @@ describe("loadGatewayPlugins", () => {
|
||||
});
|
||||
expect(resolveGatewayStartupPluginIds).toHaveBeenCalledWith({
|
||||
config: {},
|
||||
activationSourceConfig: undefined,
|
||||
workspaceDir: "/tmp",
|
||||
env: process.env,
|
||||
});
|
||||
@@ -308,6 +309,7 @@ describe("loadGatewayPlugins", () => {
|
||||
|
||||
expect(resolveGatewayStartupPluginIds).toHaveBeenCalledWith({
|
||||
config: autoEnabledConfig,
|
||||
activationSourceConfig: undefined,
|
||||
workspaceDir: "/tmp",
|
||||
env: process.env,
|
||||
});
|
||||
@@ -343,6 +345,12 @@ describe("loadGatewayPlugins", () => {
|
||||
config: rawConfig,
|
||||
env: process.env,
|
||||
});
|
||||
expect(resolveGatewayStartupPluginIds).toHaveBeenCalledWith({
|
||||
config: resolvedConfig,
|
||||
activationSourceConfig: rawConfig,
|
||||
workspaceDir: "/tmp",
|
||||
env: process.env,
|
||||
});
|
||||
expect(loadOpenClawPlugins).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
config: resolvedConfig,
|
||||
|
||||
@@ -423,6 +423,7 @@ export function loadGatewayPlugins(params: {
|
||||
params.pluginIds ??
|
||||
resolveGatewayStartupPluginIds({
|
||||
config: resolvedConfig,
|
||||
activationSourceConfig: params.activationSourceConfig,
|
||||
workspaceDir: params.workspaceDir,
|
||||
env: process.env,
|
||||
});
|
||||
|
||||
@@ -602,6 +602,7 @@ export async function startGatewayServer(
|
||||
? []
|
||||
: resolveGatewayStartupPluginIds({
|
||||
config: gatewayPluginConfigAtStart,
|
||||
activationSourceConfig: cfgAtStart,
|
||||
workspaceDir: defaultWorkspaceDir,
|
||||
env: process.env,
|
||||
});
|
||||
|
||||
@@ -70,22 +70,30 @@ function createManifestRegistryFixture() {
|
||||
};
|
||||
}
|
||||
|
||||
function expectStartupPluginIds(config: OpenClawConfig, expected: readonly string[]) {
|
||||
function expectStartupPluginIds(params: {
|
||||
config: OpenClawConfig;
|
||||
activationSourceConfig?: OpenClawConfig;
|
||||
expected: readonly string[];
|
||||
}) {
|
||||
expect(
|
||||
resolveGatewayStartupPluginIds({
|
||||
config,
|
||||
config: params.config,
|
||||
...(params.activationSourceConfig !== undefined
|
||||
? { activationSourceConfig: params.activationSourceConfig }
|
||||
: {}),
|
||||
workspaceDir: "/tmp",
|
||||
env: process.env,
|
||||
}),
|
||||
).toEqual(expected);
|
||||
).toEqual(params.expected);
|
||||
expect(loadPluginManifestRegistry).toHaveBeenCalled();
|
||||
}
|
||||
|
||||
function expectStartupPluginIdsCase(params: {
|
||||
config: OpenClawConfig;
|
||||
activationSourceConfig?: OpenClawConfig;
|
||||
expected: readonly string[];
|
||||
}) {
|
||||
expectStartupPluginIds(params.config, params.expected);
|
||||
expectStartupPluginIds(params);
|
||||
}
|
||||
|
||||
function createStartupConfig(params: {
|
||||
@@ -211,4 +219,27 @@ describe("resolveGatewayStartupPluginIds", () => {
|
||||
] as const)("%s", (_name, config, expected) => {
|
||||
expectStartupPluginIdsCase({ config, expected });
|
||||
});
|
||||
|
||||
it("keeps effective-only bundled sidecars behind restrictive allowlists", () => {
|
||||
const rawConfig = createStartupConfig({
|
||||
allowPluginIds: ["browser"],
|
||||
});
|
||||
const effectiveConfig = {
|
||||
...rawConfig,
|
||||
plugins: {
|
||||
allow: ["browser"],
|
||||
entries: {
|
||||
"voice-call": {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
|
||||
expectStartupPluginIdsCase({
|
||||
config: effectiveConfig,
|
||||
activationSourceConfig: rawConfig,
|
||||
expected: ["demo-channel", "browser"],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -75,6 +75,7 @@ export function resolveConfiguredDeferredChannelPluginIds(params: {
|
||||
|
||||
export function resolveGatewayStartupPluginIds(params: {
|
||||
config: OpenClawConfig;
|
||||
activationSourceConfig?: OpenClawConfig;
|
||||
workspaceDir?: string;
|
||||
env: NodeJS.ProcessEnv;
|
||||
}): string[] {
|
||||
@@ -82,6 +83,9 @@ export function resolveGatewayStartupPluginIds(params: {
|
||||
listPotentialConfiguredChannelIds(params.config, params.env).map((id) => id.trim()),
|
||||
);
|
||||
const pluginsConfig = normalizePluginsConfig(params.config.plugins);
|
||||
const sourcePluginsConfig = normalizePluginsConfig(
|
||||
(params.activationSourceConfig ?? params.config).plugins,
|
||||
);
|
||||
return loadPluginManifestRegistry({
|
||||
config: params.config,
|
||||
workspaceDir: params.workspaceDir,
|
||||
@@ -100,6 +104,8 @@ export function resolveGatewayStartupPluginIds(params: {
|
||||
config: pluginsConfig,
|
||||
rootConfig: params.config,
|
||||
enabledByDefault: plugin.enabledByDefault,
|
||||
sourceConfig: sourcePluginsConfig,
|
||||
sourceRootConfig: params.activationSourceConfig ?? params.config,
|
||||
});
|
||||
if (!activationState.enabled) {
|
||||
return false;
|
||||
|
||||
@@ -287,7 +287,8 @@ export function resolvePluginActivationState(params: {
|
||||
});
|
||||
const explicitlyConfiguredBundledChannel =
|
||||
params.origin === "bundled" &&
|
||||
isBundledChannelEnabledByChannelConfig(params.sourceRootConfig ?? params.rootConfig, params.id);
|
||||
explicitSelection.explicitlyEnabled &&
|
||||
explicitSelection.reason === "channel enabled in config";
|
||||
|
||||
if (!params.config.enabled) {
|
||||
return {
|
||||
|
||||
@@ -3,7 +3,6 @@ import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { createJiti } from "jiti";
|
||||
import type { ChannelPlugin } from "../channels/plugins/types.js";
|
||||
import { normalizeChatChannelId } from "../channels/registry.js";
|
||||
import { isChannelConfigured } from "../config/channel-configured.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import type { PluginInstallRecord } from "../config/types.plugins.js";
|
||||
@@ -1167,12 +1166,8 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi
|
||||
config: normalized,
|
||||
rootConfig: cfg,
|
||||
enabledByDefault: manifestRecord.enabledByDefault,
|
||||
...(normalizeChatChannelId(pluginId)
|
||||
? {
|
||||
sourceConfig: activationSourceNormalized,
|
||||
sourceRootConfig: activationSourceConfig,
|
||||
}
|
||||
: {}),
|
||||
sourceConfig: activationSourceNormalized,
|
||||
sourceRootConfig: activationSourceConfig,
|
||||
});
|
||||
const entry = normalized.entries[pluginId];
|
||||
const record = createPluginRecord({
|
||||
@@ -1724,12 +1719,8 @@ export async function loadOpenClawPluginCliRegistry(
|
||||
config: normalized,
|
||||
rootConfig: cfg,
|
||||
enabledByDefault: manifestRecord.enabledByDefault,
|
||||
...(normalizeChatChannelId(pluginId)
|
||||
? {
|
||||
sourceConfig: activationSourceNormalized,
|
||||
sourceRootConfig: activationSourceConfig,
|
||||
}
|
||||
: {}),
|
||||
sourceConfig: activationSourceNormalized,
|
||||
sourceRootConfig: activationSourceConfig,
|
||||
});
|
||||
const entry = normalized.entries[pluginId];
|
||||
const record = createPluginRecord({
|
||||
|
||||
Reference in New Issue
Block a user