Expose plugin pages at /plugin/:id/page/:path

Add a public route to serve plugin extension pages without auth and update related pieces accordingly. Backend: register GET /plugin/:pluginId/page/:pagePath to locate the plugin router, validate page and HTML file existence, and send the file (returns appropriate 4xx/5xx errors). Frontend: switch iframe and new-window URLs to the new unauthenticated route (remove webui_token usage). Builtin plugin: clarify page registration comment and add a log line for the extension page URL. Minor formatting whitespace tweaks in plugin manager type annotations.
This commit is contained in:
手瓜一十雪
2026-02-02 15:40:18 +08:00
parent e7e31972e5
commit f6cca2b858
5 changed files with 44 additions and 9 deletions

View File

@@ -63,13 +63,12 @@ export default function ExtensionPage () {
}, [extensionPages]);
// 获取当前选中页面的 iframe URL
// 新路由格式不需要鉴权: /plugin/:pluginId/page/:pagePath
const currentPageUrl = useMemo(() => {
if (!selectedTab) return '';
const [pluginId, ...pathParts] = selectedTab.split(':');
const path = pathParts.join(':').replace(/^\//, '');
// 获取认证 token
const token = localStorage.getItem('token') || '';
return `/api/Plugin/page/${pluginId}/${path}?webui_token=${token}`;
return `/plugin/${pluginId}/page/${path}`;
}, [selectedTab]);
useEffect(() => {
@@ -86,11 +85,10 @@ export default function ExtensionPage () {
setIframeLoading(false);
};
// 在新窗口打开页面
// 在新窗口打开页面(新路由不需要鉴权)
const openInNewWindow = (pluginId: string, path: string) => {
const cleanPath = path.replace(/^\//, '');
const token = localStorage.getItem('token') || '';
const url = `/api/Plugin/page/${pluginId}/${cleanPath}?webui_token=${token}`;
const url = `/plugin/${pluginId}/page/${cleanPath}`;
window.open(url, '_blank');
};