feat: admin audit log — merged PR #118

Audit logging for admin actions, backups, auth events.
New AuditLogPanel in Admin tab with pagination.
Dockerfile security: run as non-root user.
i18n keys for all 9 languages.

Thanks @fgbona for the implementation!
This commit is contained in:
Maurice
2026-03-30 20:05:32 +02:00
21 changed files with 574 additions and 20 deletions

View File

@@ -320,6 +320,7 @@ const ar: Record<string, string | { name: string; category: string }[]> = {
'admin.tabs.users': 'المستخدمون',
'admin.tabs.categories': 'الفئات',
'admin.tabs.backup': 'النسخ الاحتياطي',
'admin.tabs.audit': 'سجل التدقيق',
'admin.tabs.settings': 'الإعدادات',
'admin.tabs.config': 'الإعدادات',
'admin.tabs.templates': 'قوالب التعبئة',
@@ -463,6 +464,18 @@ const ar: Record<string, string | { name: string; category: string }[]> = {
'admin.weather.locationHint': 'يعتمد الطقس على أول مكان بإحداثيات في كل يوم. إذا لم يكن هناك مكان مخصص ليوم ما، يُستخدم أي مكان من قائمة الأماكن كمرجع.',
// GitHub
'admin.audit.subtitle': 'أحداث الأمان والإدارة (النسخ الاحتياطية، المستخدمون، المصادقة الثنائية، الإعدادات).',
'admin.audit.empty': 'لا توجد سجلات تدقيق بعد.',
'admin.audit.refresh': 'تحديث',
'admin.audit.loadMore': 'تحميل المزيد',
'admin.audit.showing': 'تم تحميل {count} · الإجمالي {total}',
'admin.audit.col.time': 'الوقت',
'admin.audit.col.user': 'المستخدم',
'admin.audit.col.action': 'الإجراء',
'admin.audit.col.resource': 'المورد',
'admin.audit.col.ip': 'عنوان IP',
'admin.audit.col.details': 'التفاصيل',
'admin.github.title': 'سجل الإصدارات',
'admin.github.subtitle': 'آخر التحديثات من {repo}',
'admin.github.latest': 'الأحدث',

View File

@@ -315,6 +315,7 @@ const de: Record<string, string | { name: string; category: string }[]> = {
'admin.tabs.users': 'Benutzer',
'admin.tabs.categories': 'Kategorien',
'admin.tabs.backup': 'Backup',
'admin.tabs.audit': 'Audit-Protokoll',
'admin.stats.users': 'Benutzer',
'admin.stats.trips': 'Reisen',
'admin.stats.places': 'Orte',
@@ -418,8 +419,6 @@ const de: Record<string, string | { name: string; category: string }[]> = {
'admin.tabs.addons': 'Addons',
'admin.addons.title': 'Addons',
'admin.addons.subtitle': 'Aktiviere oder deaktiviere Funktionen, um TREK nach deinen Wünschen anzupassen.',
'admin.addons.catalog.memories.name': 'Erinnerungen',
'admin.addons.catalog.memories.description': 'Geteilte Fotoalben für jede Reise',
'admin.addons.catalog.packing.name': 'Packliste',
'admin.addons.catalog.packing.description': 'Checklisten zum Kofferpacken für jede Reise',
'admin.addons.catalog.budget.name': 'Budget',
@@ -459,6 +458,19 @@ const de: Record<string, string | { name: string; category: string }[]> = {
// GitHub
'admin.tabs.github': 'GitHub',
'admin.audit.subtitle': 'Sicherheitsrelevante und administrative Ereignisse (Backups, Benutzer, MFA, Einstellungen).',
'admin.audit.empty': 'Noch keine Audit-Einträge.',
'admin.audit.refresh': 'Aktualisieren',
'admin.audit.loadMore': 'Mehr laden',
'admin.audit.showing': '{count} geladen · {total} gesamt',
'admin.audit.col.time': 'Zeit',
'admin.audit.col.user': 'Benutzer',
'admin.audit.col.action': 'Aktion',
'admin.audit.col.resource': 'Ressource',
'admin.audit.col.ip': 'IP',
'admin.audit.col.details': 'Details',
'admin.github.title': 'Update-Verlauf',
'admin.github.subtitle': 'Neueste Updates von {repo}',
'admin.github.latest': 'Aktuell',

View File

@@ -315,6 +315,7 @@ const en: Record<string, string | { name: string; category: string }[]> = {
'admin.tabs.users': 'Users',
'admin.tabs.categories': 'Categories',
'admin.tabs.backup': 'Backup',
'admin.tabs.audit': 'Audit log',
'admin.stats.users': 'Users',
'admin.stats.trips': 'Trips',
'admin.stats.places': 'Places',
@@ -418,8 +419,6 @@ const en: Record<string, string | { name: string; category: string }[]> = {
'admin.tabs.addons': 'Addons',
'admin.addons.title': 'Addons',
'admin.addons.subtitle': 'Enable or disable features to customize your TREK experience.',
'admin.addons.catalog.memories.name': 'Memories',
'admin.addons.catalog.memories.description': 'Shared photo albums for each trip',
'admin.addons.catalog.packing.name': 'Packing',
'admin.addons.catalog.packing.description': 'Checklists to prepare your luggage for each trip',
'admin.addons.catalog.budget.name': 'Budget',
@@ -459,6 +458,18 @@ const en: Record<string, string | { name: string; category: string }[]> = {
// GitHub
'admin.tabs.github': 'GitHub',
'admin.audit.subtitle': 'Security-sensitive and administration events (backups, users, MFA, settings).',
'admin.audit.empty': 'No audit entries yet.',
'admin.audit.refresh': 'Refresh',
'admin.audit.loadMore': 'Load more',
'admin.audit.showing': '{count} loaded · {total} total',
'admin.audit.col.time': 'Time',
'admin.audit.col.user': 'User',
'admin.audit.col.action': 'Action',
'admin.audit.col.resource': 'Resource',
'admin.audit.col.ip': 'IP',
'admin.audit.col.details': 'Details',
'admin.github.title': 'Release History',
'admin.github.subtitle': 'Latest updates from {repo}',
'admin.github.latest': 'Latest',

View File

@@ -313,6 +313,7 @@ const es: Record<string, string> = {
'admin.tabs.users': 'Usuarios',
'admin.tabs.categories': 'Categorías',
'admin.tabs.backup': 'Copia de seguridad',
'admin.tabs.audit': 'Registro de auditoría',
'admin.stats.users': 'Usuarios',
'admin.stats.trips': 'Viajes',
'admin.stats.places': 'Lugares',
@@ -437,6 +438,19 @@ const es: Record<string, string> = {
// GitHub
'admin.tabs.github': 'GitHub',
'admin.audit.subtitle': 'Eventos sensibles de seguridad y administración (copias de seguridad, usuarios, MFA, ajustes).',
'admin.audit.empty': 'Aún no hay entradas de auditoría.',
'admin.audit.refresh': 'Actualizar',
'admin.audit.loadMore': 'Cargar más',
'admin.audit.showing': '{count} cargados · {total} en total',
'admin.audit.col.time': 'Fecha y hora',
'admin.audit.col.user': 'Usuario',
'admin.audit.col.action': 'Acción',
'admin.audit.col.resource': 'Recurso',
'admin.audit.col.ip': 'IP',
'admin.audit.col.details': 'Detalles',
'admin.github.title': 'Historial de versiones',
'admin.github.subtitle': 'Últimas novedades de {repo}',
'admin.github.latest': 'Última',

View File

@@ -315,6 +315,7 @@ const nl: Record<string, string> = {
'admin.tabs.users': 'Gebruikers',
'admin.tabs.categories': 'Categorieën',
'admin.tabs.backup': 'Back-up',
'admin.tabs.audit': 'Auditlog',
'admin.stats.users': 'Gebruikers',
'admin.stats.trips': 'Reizen',
'admin.stats.places': 'Plaatsen',
@@ -456,6 +457,19 @@ const nl: Record<string, string> = {
// GitHub
'admin.tabs.github': 'GitHub',
'admin.audit.subtitle': 'Beveiligingsgevoelige en beheerdersgebeurtenissen (back-ups, gebruikers, MFA, instellingen).',
'admin.audit.empty': 'Nog geen auditregistraties.',
'admin.audit.refresh': 'Vernieuwen',
'admin.audit.loadMore': 'Meer laden',
'admin.audit.showing': '{count} geladen · {total} totaal',
'admin.audit.col.time': 'Tijd',
'admin.audit.col.user': 'Gebruiker',
'admin.audit.col.action': 'Actie',
'admin.audit.col.resource': 'Bron',
'admin.audit.col.ip': 'IP',
'admin.audit.col.details': 'Details',
'admin.github.title': 'Release-geschiedenis',
'admin.github.subtitle': 'Laatste updates van {repo}',
'admin.github.latest': 'Nieuwste',

View File

@@ -315,6 +315,7 @@ const ru: Record<string, string> = {
'admin.tabs.users': 'Пользователи',
'admin.tabs.categories': 'Категории',
'admin.tabs.backup': 'Резервная копия',
'admin.tabs.audit': 'Журнал аудита',
'admin.stats.users': 'Пользователи',
'admin.stats.trips': 'Поездки',
'admin.stats.places': 'Места',
@@ -456,6 +457,19 @@ const ru: Record<string, string> = {
// GitHub
'admin.tabs.github': 'GitHub',
'admin.audit.subtitle': 'События, связанные с безопасностью и администрированием (резервные копии, пользователи, MFA, настройки).',
'admin.audit.empty': 'Записей аудита пока нет.',
'admin.audit.refresh': 'Обновить',
'admin.audit.loadMore': 'Загрузить ещё',
'admin.audit.showing': 'Загружено: {count} · всего {total}',
'admin.audit.col.time': 'Время',
'admin.audit.col.user': 'Пользователь',
'admin.audit.col.action': 'Действие',
'admin.audit.col.resource': 'Объект',
'admin.audit.col.ip': 'IP',
'admin.audit.col.details': 'Подробности',
'admin.github.title': 'История релизов',
'admin.github.subtitle': 'Последние обновления из {repo}',
'admin.github.latest': 'Последний',

View File

@@ -315,6 +315,7 @@ const zh: Record<string, string> = {
'admin.tabs.users': '用户',
'admin.tabs.categories': '分类',
'admin.tabs.backup': '备份',
'admin.tabs.audit': '审计日志',
'admin.stats.users': '用户',
'admin.stats.trips': '旅行',
'admin.stats.places': '地点',
@@ -456,6 +457,19 @@ const zh: Record<string, string> = {
// GitHub
'admin.tabs.github': 'GitHub',
'admin.audit.subtitle': '安全与管理员操作记录备份、用户、MFA、设置。',
'admin.audit.empty': '暂无审计记录。',
'admin.audit.refresh': '刷新',
'admin.audit.loadMore': '加载更多',
'admin.audit.showing': '已加载 {count} 条 · 共 {total} 条',
'admin.audit.col.time': '时间',
'admin.audit.col.user': '用户',
'admin.audit.col.action': '操作',
'admin.audit.col.resource': '资源',
'admin.audit.col.ip': 'IP',
'admin.audit.col.details': '详情',
'admin.github.title': '版本历史',
'admin.github.subtitle': '{repo} 的最新更新',
'admin.github.latest': '最新',