From 62f25fe524c1dcf09ac3a07be70b4c73f9ff0498 Mon Sep 17 00:00:00 2001 From: longsizhuo Date: Fri, 17 Apr 2026 20:45:52 +0000 Subject: [PATCH 1/5] =?UTF-8?q?feat(admin):=20/admin/database=20=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E5=B5=8C=E5=85=A5=20pgAdmin=20iframe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 管理员用一个主站入口进 pgAdmin 做备份/恢复/查表/跑 SQL,不再打开 api.involutionhell.com:8082 这种裸页面。pgAdmin 本身的 UI 风格跟主站不搭, 但用户明确说"管理员不配享受好 UI",优先接通能力。 - 新增 app/admin/database/page.tsx:AdminGuard 兜底权限,iframe src 走 https://api.involutionhell.com/admin/pgadmin/(可由 NEXT_PUBLIC_PGADMIN_URL 覆盖) - /admin 首页加"数据库管理"入口卡片 真实的权限/流量控制在后端 compose + Caddy 那边(见 involutionhell-backend#12): Caddy 反向代理 /admin/pgadmin/* 到 127.0.0.1:8082,剥 X-Frame-Options, 下发 CSP frame-ancestors 放行 involutionhell.com 主域。 --- app/admin/database/page.tsx | 85 +++++++++++++++++++++++++++++++++++++ app/admin/page.tsx | 10 ++++- 2 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 app/admin/database/page.tsx diff --git a/app/admin/database/page.tsx b/app/admin/database/page.tsx new file mode 100644 index 0000000..654f03a --- /dev/null +++ b/app/admin/database/page.tsx @@ -0,0 +1,85 @@ +"use client"; + +/** + * /admin/database — 数据库管理后台(iframe 嵌入 pgAdmin)。 + * + * 权限: 兜底,非 admin 直接 403; + * 真正的操作权限由 pgAdmin 自身登录(环境变量里的 PGADMIN_EMAIL / PGADMIN_PASSWORD) + * 把守,前端这层只是"路由可见"。 + * + * 流量: + * 浏览器 → involutionhell.com/admin/database + * └─ iframe src="https://api.involutionhell.com/admin/pgadmin/" + * └─ Caddy /admin/pgadmin/* → 127.0.0.1:8082(pgAdmin 容器) + * + * pgAdmin 容器环境里设了 SCRIPT_NAME=/admin/pgadmin, + * Caddy 响应里剥掉 X-Frame-Options 并换成 CSP frame-ancestors 放行本站主域。 + * + * 为什么不把 pgAdmin 和主站 UI 做统一风格: + * 用户明确说"管理员不配享受好 UI"——优先把基础能力接通,视觉一致性排最后。 + */ + +import { AdminGuard } from "../events/AdminGuard"; + +// pgAdmin 所在路径。默认打 production Caddy,dev 如果要本地联调可以用 +// NEXT_PUBLIC_PGADMIN_URL 覆盖(比如指到 http://localhost:8082/admin/pgadmin/)。 +const PGADMIN_URL = + process.env.NEXT_PUBLIC_PGADMIN_URL ?? + "https://api.involutionhell.com/admin/pgadmin/"; + +export default function AdminDatabasePage() { + return ( + + + + ); +} + +function AdminDatabaseInner() { + return ( +
+
+
+
+ Admin · Database +
+

+ 数据库管理 +

+

+ 下方嵌入的是 pgAdmin。首次进入要用{" "} + + PGADMIN_EMAIL + {" "} + /{" "} + + PGADMIN_PASSWORD + {" "} + 登录(在{" "} + + .env + {" "} + 里)。 左树自动预注册了 “InvolutionHell (local)” + 连接,双击即连。 备份/恢复在数据库右键菜单里;定时备份落在{" "} + + Storage → backups/ + + 。 +

+
+
+ + {/* iframe 占满剩余视口,便于操作。高度用 calc 减去 header 高度约 220px。 */} +
+