fix(plugins): skip community trust dialog for official plugins

Official marketplace plugins already show the official auto-update badge, but the first-enable confirmation still used community-plugin copy. Skip that confirmation for publisher EdgeEver plugins; community plugins still get the one-time warning.
This commit is contained in:
tianma-if committed 2026-09-09 20:59:34 +08:00
1 parent ba56c5883c
commit d3600a9d52
6 files changed
+48 -9

No files matched your search

@@ -40,4 +40,9 @@ describe("unified plugin catalog cards", () => {
expect(catalogCard).not.toContain("marketplace.installed");
expect(source).not.toContain("border-emerald-100");
});
test("does not treat official marketplace plugins as community plugins in the trust dialog", () => {
expect(source).toContain("getPluginCatalogSourceKey(catalogItem) === \"official\"");
expect(source).toContain("isOfficial:");
});
});
@@ -15,7 +15,7 @@ import { GitHubMark } from "@/components/GitHubRepositoryLink";
import { applyPluginUpdate, checkPluginUpdates, type PluginUpdateInfo } from "@/lib/plugins/plugin-updates";
import { PluginUpdateDialog } from "@/components/plugins/PluginUpdateDialog";
import { PluginSettingsSection } from "@/components/plugins/PluginSettingsSection";
import { buildPluginCatalogItems } from "@/lib/plugins/plugin-catalog";
import { buildPluginCatalogItems, getPluginCatalogSourceKey } from "@/lib/plugins/plugin-catalog";
import { getPluginDetailPage, getPluginDetailPath, hasPluginSettings, type PluginDetailPage } from "@/lib/plugins/plugin-navigation";
import type { ScheduledTask } from "@edgeever/shared";
import { api, getOrCreateClientDeviceId } from "@/lib/api";
@@ -391,10 +391,13 @@ export const PluginManagerCard = ({
};
const toggleExtension = (extension: InstalledExtension, enabled: boolean) => {
const catalogItem = catalogItems.find((item) => item.id === extension.manifest.id)
?? { id: extension.manifest.id, extension };
if (shouldRequestPluginTrustAcknowledgement({
acknowledged: hasAcknowledgedPluginTrustWarning(),
enabled,
extensionType: extension.manifest.type,
isOfficial: getPluginCatalogSourceKey(catalogItem) === "official",
})) {
setPendingTrustPluginId(extension.manifest.id);
return;
+34 -5
View File
@@ -34,10 +34,39 @@ describe("plugin trust acknowledgement", () => {
expect(() => acknowledgePluginTrustWarning(storage)).not.toThrow();
});
test("asks only before the first client-plugin enable", () => {
expect(shouldRequestPluginTrustAcknowledgement({ acknowledged: false, enabled: true, extensionType: "plugin" })).toBe(true);
expect(shouldRequestPluginTrustAcknowledgement({ acknowledged: true, enabled: true, extensionType: "plugin" })).toBe(false);
expect(shouldRequestPluginTrustAcknowledgement({ acknowledged: false, enabled: false, extensionType: "plugin" })).toBe(false);
expect(shouldRequestPluginTrustAcknowledgement({ acknowledged: false, enabled: true, extensionType: "theme" })).toBe(false);
test("asks only before the first community client-plugin enable", () => {
expect(shouldRequestPluginTrustAcknowledgement({
acknowledged: false,
enabled: true,
extensionType: "plugin",
isOfficial: false,
})).toBe(true);
expect(shouldRequestPluginTrustAcknowledgement({
acknowledged: true,
enabled: true,
extensionType: "plugin",
isOfficial: false,
})).toBe(false);
expect(shouldRequestPluginTrustAcknowledgement({
acknowledged: false,
enabled: false,
extensionType: "plugin",
isOfficial: false,
})).toBe(false);
expect(shouldRequestPluginTrustAcknowledgement({
acknowledged: false,
enabled: true,
extensionType: "theme",
isOfficial: false,
})).toBe(false);
});
test("does not treat official plugins as community plugins", () => {
expect(shouldRequestPluginTrustAcknowledgement({
acknowledged: false,
enabled: true,
extensionType: "plugin",
isOfficial: true,
})).toBe(false);
});
});
+3 -1
View File
@@ -41,8 +41,10 @@ export const shouldRequestPluginTrustAcknowledgement = ({
acknowledged,
enabled,
extensionType,
isOfficial,
}: {
acknowledged: boolean;
enabled: boolean;
extensionType: "plugin" | "theme";
}) => enabled && extensionType === "plugin" && !acknowledged;
isOfficial: boolean;
}) => enabled && extensionType === "plugin" && !acknowledged && !isOfficial;
+1 -1
View File
@@ -8,7 +8,7 @@ Theme packages contain only a validated manifest and documented design tokens. T
Client plugins use an Obsidian-style trusted-code model. Enabling a plugin trusts it with the full EdgeEver plugin context; declared capabilities are optional descriptive metadata and do not gate API calls. The plugin module runs in the client JavaScript environment, so users must install plugins only from developers they trust.
The first time a user enables a client plugin on a device, EdgeEver presents a community-plugin trust confirmation. Once acknowledged, it is not shown for every plugin. Theme packages do not trigger the confirmation because they cannot execute JavaScript.
The first time a user enables a community client plugin on a device, EdgeEver presents a community-plugin trust confirmation. Once acknowledged, it is not shown for every plugin. Official plugins (publisher EdgeEver) do not trigger the confirmation. Theme packages also do not trigger it because they cannot execute JavaScript.
Plugins never receive EdgeEver's repository, IndexedDB database, Cloudflare bindings, or internal React state through the public API.
+1 -1
View File
@@ -8,7 +8,7 @@ EdgeEver P0 扩展 API 支持受信任的客户端插件和无代码主题包。
客户端插件采用类似 Obsidian 的受信任代码模型。启用插件即代表信任它使用完整的 EdgeEver 插件上下文;能力声明只是可选的描述性元数据,不限制 API 调用。插件模块运行在客户端 JavaScript 环境中,因此用户只能安装来自可信开发者的插件。
用户在一台设备上首次启用客户端插件时,EdgeEver 会显示一次社区插件信任确认;确认后不会对每个插件重复提示。主题包不能执行 JavaScript,因此不会触发该确认。
用户在一台设备上首次启用社区客户端插件时,EdgeEver 会显示一次社区插件信任确认;确认后不会对每个插件重复提示。官方插件(发布者为 EdgeEver)不会触发该确认。主题包不能执行 JavaScript,因此也不会触发该确认。
公开 API 不会向插件暴露 EdgeEver Repository、IndexedDB 数据库、Cloudflare Binding 或 React 内部状态。