Add audit log functionality to track user activity and data changes.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 705f2157-ef97-4fbd-89e4-8c7f2ecaea90
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7ed01c5f-a82d-405a-b728-b2e3d127c60c/3d6885b0-d066-41b0-8042-fa2b629d3709.jpg
This commit is contained in:
alphaeusmote
2025-04-09 01:56:37 +00:00
parent 067cdacde8
commit c52c024ccc
6 changed files with 896 additions and 13 deletions
+41 -3
View File
@@ -5,15 +5,15 @@ import {
AdOrgUnit, InsertAdOrgUnit, AdComputer, InsertAdComputer,
AdDomain, InsertAdDomain, Role, ApiQuery,
LdapFilter, InsertLdapFilter, LdapFilterRevision, InsertLdapFilterRevision,
LdapAttribute, InsertLdapAttribute,
LdapAttribute, InsertLdapAttribute, AuditLog, InsertAuditLog,
users, apiTokens, ldapConnections, adUsers, adGroups, adOrgUnits, adComputers, adDomains,
roles, ldapFilters, ldapFilterRevisions, ldapAttributes
roles, ldapFilters, ldapFilterRevisions, ldapAttributes, auditLogs
} from "@shared/schema";
import session from "express-session";
import createMemoryStore from "memorystore";
import crypto from "crypto";
import { db } from "./db";
import { eq, and, type SQL } from "drizzle-orm";
import { eq, and, type SQL, desc } from "drizzle-orm";
import connectPg from "connect-pg-simple";
import { Pool } from "@neondatabase/serverless";
import { applyQueryOptions } from "./query-parser";
@@ -112,6 +112,10 @@ export interface IStorage {
updateAdDomain(id: number, domain: Partial<AdDomain>): Promise<AdDomain | undefined>;
deleteAdDomain(id: number): Promise<boolean>;
listAdDomains(connectionId: number, query?: any): Promise<AdDomain[]>;
// Audit logging
createAuditLogEntry(entry: InsertAuditLog): Promise<AuditLog>;
getAuditLogs(connectionId?: number, userId?: number): Promise<AuditLog[]>;
// Session store
sessionStore: any;
@@ -855,6 +859,40 @@ export class DatabaseStorage implements IStorage {
return adDomainsQuery;
}
// Audit logging
async createAuditLogEntry(entry: InsertAuditLog): Promise<AuditLog> {
debug(`Creating audit log entry: ${JSON.stringify(entry)}`);
const result = await db.insert(auditLogs).values({
...entry,
timestamp: new Date() // Ensure timestamp is set
}).returning();
return result[0];
}
async getAuditLogs(connectionId?: number, userId?: number): Promise<AuditLog[]> {
debug(`Getting audit logs: connectionId=${connectionId}, userId=${userId}`);
// Define the base query
let query = db.select().from(auditLogs);
// Apply filters if provided
if (connectionId !== undefined && userId !== undefined) {
query = query.where(
and(
eq(auditLogs.connectionId, connectionId),
eq(auditLogs.userId, userId)
)
);
} else if (connectionId !== undefined) {
query = query.where(eq(auditLogs.connectionId, connectionId));
} else if (userId !== undefined) {
query = query.where(eq(auditLogs.userId, userId));
}
// Sort by most recent first
return await query.orderBy(desc(auditLogs.timestamp));
}
}
export const storage = new DatabaseStorage();