Add comprehensive ISAC audit logging
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import { requirePermission } from '$lib/server/auth/authorization';
|
||||
import { getSessionUser } from '$lib/server/auth/session';
|
||||
import { getDatabase } from '$lib/server/database';
|
||||
import { getPagination } from '$lib/server/pagination';
|
||||
import type { PageServerLoad } from './$types';
|
||||
|
||||
export const load: PageServerLoad = async ({ cookies, url }) => {
|
||||
await requirePermission(await getSessionUser(cookies), 'audit.view');
|
||||
const database = await getDatabase();
|
||||
const query = url.searchParams.get('q')?.trim().slice(0, 120) ?? '';
|
||||
const category = url.searchParams.get('category')?.trim() ?? '';
|
||||
const action = url.searchParams.get('action')?.trim() ?? '';
|
||||
const conditions: string[] = [];
|
||||
const args: unknown[] = [];
|
||||
if (query) {
|
||||
conditions.push(`(audit_log.entity_id LIKE ? ESCAPE '\\' COLLATE NOCASE
|
||||
OR audit_log.before_json LIKE ? ESCAPE '\\' COLLATE NOCASE
|
||||
OR audit_log.after_json LIKE ? ESCAPE '\\' COLLATE NOCASE
|
||||
OR users.username LIKE ? ESCAPE '\\' COLLATE NOCASE
|
||||
OR user_profiles.display_name LIKE ? ESCAPE '\\' COLLATE NOCASE)`);
|
||||
const pattern = `%${query.replaceAll('%', '\\%').replaceAll('_', '\\_')}%`;
|
||||
args.push(pattern, pattern, pattern, pattern, pattern);
|
||||
}
|
||||
if (category === 'user') conditions.push("audit_log.entity_type IN ('user','user_access','user_moderation','identity')");
|
||||
else if (category === 'access_policy') conditions.push("audit_log.entity_type IN ('role','role_management')");
|
||||
else if (category) { conditions.push('audit_log.entity_type=?'); args.push(category); }
|
||||
if (action) { conditions.push('audit_log.action=?'); args.push(action); }
|
||||
const where = conditions.length ? `WHERE ${conditions.join(' AND ')}` : '';
|
||||
const [total, categories, actions, summary] = await Promise.all([
|
||||
(await database.prepare(`SELECT COUNT(*) AS total FROM audit_log
|
||||
JOIN users ON users.id=audit_log.actor_id LEFT JOIN user_profiles ON user_profiles.user_id=users.id ${where}`)).get(...args),
|
||||
(await database.prepare('SELECT entity_type,COUNT(*) AS count FROM audit_log GROUP BY entity_type ORDER BY entity_type')).all(),
|
||||
(await database.prepare('SELECT action,COUNT(*) AS count FROM audit_log GROUP BY action ORDER BY action')).all(),
|
||||
(await database.prepare(`SELECT COUNT(*) AS total,
|
||||
SUM(CASE WHEN entity_type='game_data' THEN 1 ELSE 0 END) AS game_data,
|
||||
SUM(CASE WHEN entity_type IN ('user','user_access','user_moderation','identity') THEN 1 ELSE 0 END) AS users,
|
||||
SUM(CASE WHEN entity_type IN ('role','role_management') THEN 1 ELSE 0 END) AS access
|
||||
FROM audit_log`)).get()
|
||||
]);
|
||||
const pagination = getPagination(url, Number(total?.total ?? 0));
|
||||
const entries = await (await database.prepare(`SELECT audit_log.*,
|
||||
COALESCE(user_profiles.display_name,users.username) AS actor_name,users.login_username AS actor_login
|
||||
FROM audit_log JOIN users ON users.id=audit_log.actor_id
|
||||
LEFT JOIN user_profiles ON user_profiles.user_id=users.id
|
||||
${where} ORDER BY audit_log.created_at DESC LIMIT ? OFFSET ?`)).all(...args, pagination.perPage, pagination.offset);
|
||||
return { entries, categories, actions, summary, pagination, filters: { query, category, action } };
|
||||
};
|
||||
Reference in New Issue
Block a user