From 3580f12b223a6b2c1fab26c0d29c2851d36ba10c Mon Sep 17 00:00:00 2001 From: lalitraj881 Date: Thu, 29 Jan 2026 17:59:28 +0530 Subject: [PATCH] fix: prevent plugins from auto-enabling without user consent (#3932) - Change default enabled state from true to false in enablePluginEntry() - Plugins are now configured but require explicit user enablement - Update all tests to expect enabled: false by default - Preserve explicit enabled: true values (non-destructive) This ensures plugins/skills only enable when users explicitly confirm during onboarding or manual configuration, respecting user consent. Resolves #3932 --- src/config/plugin-auto-enable.test.ts | 26 +++++++++++++------------- src/config/plugin-auto-enable.ts | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/config/plugin-auto-enable.test.ts b/src/config/plugin-auto-enable.test.ts index 8399389e3..f84900d44 100644 --- a/src/config/plugin-auto-enable.test.ts +++ b/src/config/plugin-auto-enable.test.ts @@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest"; import { applyPluginAutoEnable } from "./plugin-auto-enable.js"; describe("applyPluginAutoEnable", () => { - it("enables configured channel plugins and updates allowlist", () => { + it("configures channel plugins with disabled state and updates allowlist", () => { const result = applyPluginAutoEnable({ config: { channels: { slack: { botToken: "x" } }, @@ -11,7 +11,7 @@ describe("applyPluginAutoEnable", () => { env: {}, }); - expect(result.config.plugins?.entries?.slack?.enabled).toBe(true); + expect(result.config.plugins?.entries?.slack?.enabled).toBe(false); expect(result.config.plugins?.allow).toEqual(["telegram", "slack"]); expect(result.changes.join("\n")).toContain("Slack configured, not enabled yet."); }); @@ -29,7 +29,7 @@ describe("applyPluginAutoEnable", () => { expect(result.changes).toEqual([]); }); - it("enables provider auth plugins when profiles exist", () => { + it("configures provider auth plugins as disabled when profiles exist", () => { const result = applyPluginAutoEnable({ config: { auth: { @@ -44,7 +44,7 @@ describe("applyPluginAutoEnable", () => { env: {}, }); - expect(result.config.plugins?.entries?.["google-antigravity-auth"]?.enabled).toBe(true); + expect(result.config.plugins?.entries?.["google-antigravity-auth"]?.enabled).toBe(false); }); it("skips when plugins are globally disabled", () => { @@ -61,7 +61,7 @@ describe("applyPluginAutoEnable", () => { }); describe("preferOver channel prioritization", () => { - it("prefers bluebubbles: skips imessage auto-enable when both are configured", () => { + it("prefers bluebubbles: skips imessage auto-configure when both are configured", () => { const result = applyPluginAutoEnable({ config: { channels: { @@ -72,7 +72,7 @@ describe("applyPluginAutoEnable", () => { env: {}, }); - expect(result.config.plugins?.entries?.bluebubbles?.enabled).toBe(true); + expect(result.config.plugins?.entries?.bluebubbles?.enabled).toBe(false); expect(result.config.plugins?.entries?.imessage?.enabled).toBeUndefined(); expect(result.changes.join("\n")).toContain("bluebubbles configured, not enabled yet."); expect(result.changes.join("\n")).not.toContain("iMessage configured, not enabled yet."); @@ -90,11 +90,11 @@ describe("applyPluginAutoEnable", () => { env: {}, }); - expect(result.config.plugins?.entries?.bluebubbles?.enabled).toBe(true); + expect(result.config.plugins?.entries?.bluebubbles?.enabled).toBe(false); expect(result.config.plugins?.entries?.imessage?.enabled).toBe(true); }); - it("allows imessage auto-enable when bluebubbles is explicitly disabled", () => { + it("allows imessage auto-configure when bluebubbles is explicitly disabled", () => { const result = applyPluginAutoEnable({ config: { channels: { @@ -107,11 +107,11 @@ describe("applyPluginAutoEnable", () => { }); expect(result.config.plugins?.entries?.bluebubbles?.enabled).toBe(false); - expect(result.config.plugins?.entries?.imessage?.enabled).toBe(true); + expect(result.config.plugins?.entries?.imessage?.enabled).toBe(false); expect(result.changes.join("\n")).toContain("iMessage configured, not enabled yet."); }); - it("allows imessage auto-enable when bluebubbles is in deny list", () => { + it("allows imessage auto-configure when bluebubbles is in deny list", () => { const result = applyPluginAutoEnable({ config: { channels: { @@ -124,10 +124,10 @@ describe("applyPluginAutoEnable", () => { }); expect(result.config.plugins?.entries?.bluebubbles?.enabled).toBeUndefined(); - expect(result.config.plugins?.entries?.imessage?.enabled).toBe(true); + expect(result.config.plugins?.entries?.imessage?.enabled).toBe(false); }); - it("enables imessage normally when only imessage is configured", () => { + it("configures imessage as disabled when only imessage is configured", () => { const result = applyPluginAutoEnable({ config: { channels: { imessage: { cliPath: "/usr/local/bin/imsg" } }, @@ -135,7 +135,7 @@ describe("applyPluginAutoEnable", () => { env: {}, }); - expect(result.config.plugins?.entries?.imessage?.enabled).toBe(true); + expect(result.config.plugins?.entries?.imessage?.enabled).toBe(false); expect(result.changes.join("\n")).toContain("iMessage configured, not enabled yet."); }); }); diff --git a/src/config/plugin-auto-enable.ts b/src/config/plugin-auto-enable.ts index a7632e41f..0565dba56 100644 --- a/src/config/plugin-auto-enable.ts +++ b/src/config/plugin-auto-enable.ts @@ -322,7 +322,7 @@ function enablePluginEntry(cfg: MoltbotConfig, pluginId: string): MoltbotConfig ...cfg.plugins?.entries, [pluginId]: { ...(cfg.plugins?.entries?.[pluginId] as Record | undefined), - enabled: true, + enabled: false, }, }; return {