feat: disable plugins by default, require admin approval
This commit is contained in:
+7
-7
@@ -27,7 +27,7 @@ import {
|
||||
import { toast as appToast } from '@/stores/toast-store';
|
||||
import { useAuthStore } from '@/stores/auth-store';
|
||||
|
||||
// ─── Permission helpers ──────────────────────────────────────
|
||||
// --- Permission helpers --------------------------------------
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function getPluginExternals(): any {
|
||||
@@ -61,7 +61,7 @@ function guardedHook<T extends (...args: never[]) => unknown>(
|
||||
return bus.register(plugin.id, handler, order);
|
||||
}
|
||||
|
||||
// ─── Plugin-scoped storage ───────────────────────────────────
|
||||
// --- Plugin-scoped storage -----------------------------------
|
||||
|
||||
function createPluginStorage(pluginId: string) {
|
||||
const prefix = `plugin:${pluginId}:`;
|
||||
@@ -93,7 +93,7 @@ function createPluginStorage(pluginId: string) {
|
||||
};
|
||||
}
|
||||
|
||||
// ─── Plugin-scoped logger ────────────────────────────────────
|
||||
// --- Plugin-scoped logger ------------------------------------
|
||||
|
||||
function createPluginLogger(pluginId: string) {
|
||||
const tag = `[plugin:${pluginId}]`;
|
||||
@@ -105,7 +105,7 @@ function createPluginLogger(pluginId: string) {
|
||||
};
|
||||
}
|
||||
|
||||
// ─── PluginAPI interface ─────────────────────────────────────
|
||||
// --- PluginAPI interface -------------------------------------
|
||||
|
||||
export interface PluginAPI {
|
||||
plugin: { id: string; version: string; settings: Record<string, unknown> };
|
||||
@@ -316,7 +316,7 @@ export interface PluginHooksAPI {
|
||||
onSidebarAppChange: (handler: (...args: unknown[]) => unknown) => Disposable;
|
||||
}
|
||||
|
||||
// ─── Permission mapping for hooks ────────────────────────────
|
||||
// --- Permission mapping for hooks ----------------------------
|
||||
|
||||
const HOOK_PERMISSIONS: Record<string, Permission> = {
|
||||
// Email
|
||||
@@ -465,7 +465,7 @@ const HOOK_BUSES: Record<string, { register: (pluginId: string, handler: (...arg
|
||||
...Object.fromEntries(Object.entries(sidebarAppHooks)),
|
||||
};
|
||||
|
||||
// ─── Slot registration bridge ────────────────────────────────
|
||||
// --- Slot registration bridge --------------------------------
|
||||
// Lazy import to avoid circular dependency — plugin-store imports plugin-api indirectly
|
||||
|
||||
let registerSlotFn: ((name: SlotName, reg: { pluginId: string; component: React.ComponentType<Record<string, unknown>>; order: number }) => Disposable) | null = null;
|
||||
@@ -487,7 +487,7 @@ function registerSlot(
|
||||
return registerSlotFn(slotName, { pluginId, component, order });
|
||||
}
|
||||
|
||||
// ─── Factory ─────────────────────────────────────────────────
|
||||
// --- Factory -------------------------------------------------
|
||||
|
||||
export function createPluginAPI(plugin: InstalledPlugin): PluginAPI {
|
||||
// Build hooks proxy — each hook method checks permission and registers on the right bus
|
||||
|
||||
Reference in New Issue
Block a user