diff --git a/src/web/api/player.ts b/src/web/api/player.ts index 373a32a..007de1d 100644 --- a/src/web/api/player.ts +++ b/src/web/api/player.ts @@ -16,6 +16,13 @@ export function createPlayerRouter( ): Router { const router = Router(); + // Access check runs BEFORE the existence/resolver check so a member who is + // not allowed a bot always gets a uniform 403 — whether or not the bot + // exists — instead of a 404 that would leak which bot IDs are real. + // requireBotAccess only needs req.params.botId and req.user (set by the + // global requireAuth mounted earlier), so it works before the resolver. + router.use("/:botId", requireBotAccess("botId")); + router.use("/:botId", (req, res, next) => { const bot = botManager.getBot(req.params.botId); if (!bot) { @@ -26,8 +33,6 @@ export function createPlayerRouter( next(); }); - router.use("/:botId", requireBotAccess("botId")); - /** Map API platform string to the corresponding command flag. */ const platformFlag = (platform: unknown): string => { if (platform === "bilibili") return "-b"; diff --git a/web/src/views/Settings.vue b/web/src/views/Settings.vue index 8d94ae7..bb8e098 100755 --- a/web/src/views/Settings.vue +++ b/web/src/views/Settings.vue @@ -1326,6 +1326,7 @@ function describeAction(e: AuditEntry): string { case 'user.password_reset': return `重置 ${target} 的密码`; case 'user.password_changed': return `修改自己的密码`; case 'user.role_changed': return `变更 ${target} 的角色`; + case 'user.permissions_changed': return `权限变更 → ${target}`; default: return `${e.action} → ${target}`; } }