feat(admin): журнал аудита с ротацией и апгрейд таблицы пользователей
Добавлен audit log (solution-users-6) с retention N дней и hourly purge; таблица пользователей приведена к DNA solution-users-1 (Filters, avatar, sorting). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
e430abe98b
commit
26fc8253c3
30 files changed
+2959
-59
No files matched your search
@@ -0,0 +1,43 @@
|
||||
import type { FastifyInstance, FastifyRequest } from 'fastify'
|
||||
import {
|
||||
appendAudit,
|
||||
type AppendAuditInput,
|
||||
} from '@authportal/db'
|
||||
|
||||
export function clientIp(request: FastifyRequest): string | null {
|
||||
const forwarded = request.headers['x-forwarded-for']
|
||||
if (typeof forwarded === 'string' && forwarded.trim()) {
|
||||
return forwarded.split(',')[0]?.trim() ?? null
|
||||
}
|
||||
return request.ip ?? null
|
||||
}
|
||||
|
||||
export function safeAudit(
|
||||
app: FastifyInstance,
|
||||
input: AppendAuditInput,
|
||||
): void {
|
||||
try {
|
||||
appendAudit(app.db, input)
|
||||
} catch (err) {
|
||||
app.log.warn({ err }, 'audit_log append failed')
|
||||
}
|
||||
}
|
||||
|
||||
export function actorFromRequest(request: FastifyRequest): Pick<
|
||||
AppendAuditInput,
|
||||
'actorUserId' | 'actorEmail' | 'actorName'
|
||||
> {
|
||||
const u = request.authUser
|
||||
if (!u) {
|
||||
return {
|
||||
actorUserId: null,
|
||||
actorEmail: null,
|
||||
actorName: null,
|
||||
}
|
||||
}
|
||||
return {
|
||||
actorUserId: u.id,
|
||||
actorEmail: u.email,
|
||||
actorName: u.name,
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user