From b3a4b8bb03f50e5488889383653794fe3cb3da72 Mon Sep 17 00:00:00 2001 From: freefire Date: Fri, 18 Sep 2026 01:59:49 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=89=E5=85=A8=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E5=85=B6=E5=AE=83=E6=9C=89=E6=95=88=E4=BC=9A=E8=AF=9D=E4=B9=9F?= =?UTF-8?q?=E6=A0=87=E5=9C=A8=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 本机仍为「当前在线」,Chrome/Edge 等同时登录的其它会话显示「在线」并可剔除。 Co-authored-by: Cursor --- .cursor/project_memory.md | 2 +- frontend/app/u/[id]/LoginDevices.tsx | 13 ++++++------- frontend/app/u/[id]/page.tsx | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/.cursor/project_memory.md b/.cursor/project_memory.md index 7f13e8f..a131be8 100644 --- a/.cursor/project_memory.md +++ b/.cursor/project_memory.md @@ -72,7 +72,7 @@ - 发帖/评论:staff 直发 published,普通用户进 pending;pending 不计 comment_count(ApproveComment 时 +1,删除只减 published);公开列表仅 published;作者/staff 可经详情页看 pending/rejected(GetByIDForViewer + EnsurePostVisible) - 审核端点 7 个直挂 /api/admin/moderation/*;通过/拒绝发 approved/rejected 通知(拒绝需 reason,评论通过时补发 comment/reply 业务通知);ErrModerationForbidden→403、ErrNotPending→400 - 登录历史 login_logs:成功失败都记录(失败用户名可不存在 user_id=0);GET /api/admin/users/:id/login-logs;用户列表有 online(last_seen_at 5 分钟内绿点)/last_login_ip/last_login_at 列 -- 用户安全设置「最近登录设备」:GET /api/me/login-devices(RequireAuth,仅本人仍有效的 refresh 会话,按归一化 IP+UA 指纹去重);DELETE /api/me/login-devices/:id 剔除其它设备(吊销该指纹下除当前会话外的 refresh,JWT `fid` 使 access 立即失效,需重新输入密码)。展示设备/浏览器与原始 IP(不使用 ip2region);本机标 current=当前在线,无问号。SSR 转发 refresh cookie + 浏览器 UA/IP,直出 `/u/:id?tab=security` +- 用户安全设置「最近登录设备」:GET /api/me/login-devices(RequireAuth,仅本人仍有效的 refresh 会话,按归一化 IP+UA 指纹去重);DELETE /api/me/login-devices/:id 剔除其它设备(吊销该指纹下除当前会话外的 refresh,JWT `fid` 使 access 立即失效,需重新输入密码)。展示设备/浏览器与原始 IP(不使用 ip2region);本机标 current=当前在线,其余有效会话标在线。SSR 转发 refresh cookie + 浏览器 UA/IP,直出 `/u/:id?tab=security` - 角色变更事务内 invalidateUserSessions(token_version+1 + 撤销 refresh tokens),仅板块授权变化不下线;board_admin 授权必须 ≥1 个有效板块否则 400 - 前端:lib/roles.ts(ROLE_META:owner=Crown/--gold,super=BadgeCheck,admin=ShieldCheck,board=Shield,user=Users;lucide 无 ShieldStar)、RoleBadge 组件(truncate 用于窄列+板块名);/admin/moderation 审核队列页(待审角标 WS `moderation:changed` + 回前台 HTTP 校准,无定时轮询);Forbidden.tsx 子页守卫视图(HTTP 仍 200);用户管理 /admin/users 首列收窄 grid-cols-[minmax(0,1fr)_78px_...] - 新用户发帖有 24h 冷静期(注册接口无此限制,API 回归需 SQL 回退 created_at);CreatePostRequest.tags 是字符串不是数组 diff --git a/frontend/app/u/[id]/LoginDevices.tsx b/frontend/app/u/[id]/LoginDevices.tsx index d2952c2..ef4e53c 100644 --- a/frontend/app/u/[id]/LoginDevices.tsx +++ b/frontend/app/u/[id]/LoginDevices.tsx @@ -16,7 +16,7 @@ function DeviceIcon({ kind }: { kind: LoginDevice["device_kind"] }) { /** * 安全设置:仍有效的登录会话。 - * 本机标「当前在线」;其它设备可剔除,对方需重新输入密码登录。 + * 本机标「当前在线」;其它仍有效会话标「在线」,并可剔除。 */ export default function LoginDevices({ devices: initial }: { devices: LoginDevice[] }) { const router = useRouter(); @@ -94,14 +94,13 @@ export default function LoginDevices({ devices: initial }: { devices: LoginDevic

{formatDateTime(d.created_at)}

- {d.current ? ( -

- 当前在线 -

- ) : ( +

+ {d.current ? "当前在线" : "在线"} +

+ {!d.current && (