From 1ac0f5807a8a538fa9a1ec1d86e692210243ed6a Mon Sep 17 00:00:00 2001 From: CaIon Date: Sat, 13 Jun 2026 16:12:22 +0800 Subject: [PATCH] feat(audit): add authentication method tracking in audit logs --- controller/audit.go | 8 ++++++++ middleware/audit.go | 8 ++++++++ web/default/rsbuild.config.ts | 2 +- .../usage-logs/components/dialogs/details-dialog.tsx | 12 ++++++++++++ web/default/src/features/usage-logs/types.ts | 1 + web/default/src/i18n/locales/en.json | 2 ++ web/default/src/i18n/locales/fr.json | 2 ++ web/default/src/i18n/locales/ja.json | 2 ++ web/default/src/i18n/locales/ru.json | 2 ++ web/default/src/i18n/locales/vi.json | 2 ++ web/default/src/i18n/locales/zh.json | 2 ++ 11 files changed, 42 insertions(+), 1 deletion(-) diff --git a/controller/audit.go b/controller/audit.go index 47fc4a62..2e54db4e 100644 --- a/controller/audit.go +++ b/controller/audit.go @@ -68,9 +68,17 @@ func auditOperatorInfo(c *gin.Context) map[string]interface{} { "admin_id": c.GetInt("id"), "admin_username": c.GetString("username"), "admin_role": c.GetInt("role"), + "auth_method": auditAuthMethod(c), } } +func auditAuthMethod(c *gin.Context) string { + if c.GetBool("use_access_token") { + return "access_token" + } + return "session" +} + // markAuditLogged 标记当前请求已在 handler 内手动记录审计日志, // 使鉴权链路中的审计兜底(finishAdminAudit)跳过兜底记录,避免重复。 func markAuditLogged(c *gin.Context) { diff --git a/middleware/audit.go b/middleware/audit.go index 78d84765..71b5cc43 100644 --- a/middleware/audit.go +++ b/middleware/audit.go @@ -162,6 +162,7 @@ func finishAdminAudit(c *gin.Context, writer *auditResponseWriter) { "admin_id": operatorId, "admin_username": operatorName, "admin_role": operatorRole, + "auth_method": auditAuthMethod(c), } auditInfo := map[string]interface{}{ "method": method, @@ -179,6 +180,13 @@ func finishAdminAudit(c *gin.Context, writer *auditResponseWriter) { }) } +func auditAuthMethod(c *gin.Context) string { + if c.GetBool("use_access_token") { + return "access_token" + } + return "session" +} + // auditResponseSuccess 依据 HTTP 状态码与响应体推断操作是否成功。 // 优先解析响应 JSON 中的 success 字段;无法解析时退回到状态码判断。 func auditResponseSuccess(status int, body []byte) bool { diff --git a/web/default/rsbuild.config.ts b/web/default/rsbuild.config.ts index be1d9774..4839bfce 100644 --- a/web/default/rsbuild.config.ts +++ b/web/default/rsbuild.config.ts @@ -65,7 +65,7 @@ export default defineConfig(({ envMode }) => { }, server: { host: '0.0.0.0', - strictPort: true, + strictPort: false, proxy: devProxy, }, output: { diff --git a/web/default/src/features/usage-logs/components/dialogs/details-dialog.tsx b/web/default/src/features/usage-logs/components/dialogs/details-dialog.tsx index 3fbd1f24..87571fe9 100644 --- a/web/default/src/features/usage-logs/components/dialogs/details-dialog.tsx +++ b/web/default/src/features/usage-logs/components/dialogs/details-dialog.tsx @@ -473,6 +473,12 @@ export function DetailsDialog(props: DetailsDialogProps) { if (hasUsername) return String(username) return `ID: ${id}` })() + const authMethodLabel = (() => { + if (!isManage || !props.isAdmin || !adminInfo?.auth_method) return '' + if (adminInfo.auth_method === 'access_token') return t('Access Token') + if (adminInfo.auth_method === 'session') return t('Session') + return String(adminInfo.auth_method) + })() // Localized operation text rendered from the language-independent op // descriptor (shared by audit type=3 and login type=7). @@ -806,6 +812,12 @@ export function DetailsDialog(props: DetailsDialogProps) { {operationText != null && ( )} + {authMethodLabel !== '' && ( + + )} {changedFieldsText !== '' && (