106 lines
3.8 KiB
TypeScript
106 lines
3.8 KiB
TypeScript
import * as plugins from '../../plugins.ts';
|
|
import * as interfaces from '../../../ts_interfaces/index.ts';
|
|
import type { OpsServer } from '../classes.opsserver.ts';
|
|
import { requireValidIdentity } from '../helpers/guards.ts';
|
|
import { AuditLog } from '../../models/auditlog.ts';
|
|
import { PermissionService } from '../../services/permission.service.ts';
|
|
|
|
export class AuditHandler {
|
|
public typedrouter = new plugins.typedrequest.TypedRouter();
|
|
private permissionService = new PermissionService();
|
|
|
|
constructor(private opsServerRef: OpsServer) {
|
|
this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
|
|
this.registerHandlers();
|
|
}
|
|
|
|
private registerHandlers(): void {
|
|
// Query Audit Logs
|
|
this.typedrouter.addTypedHandler(
|
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_QueryAudit>(
|
|
'queryAudit',
|
|
async (dataArg) => {
|
|
await requireValidIdentity(this.opsServerRef.authHandler, dataArg);
|
|
|
|
try {
|
|
const {
|
|
organizationId,
|
|
repositoryId,
|
|
resourceType,
|
|
actions,
|
|
success,
|
|
startDate: startDateStr,
|
|
endDate: endDateStr,
|
|
limit: limitParam,
|
|
offset: offsetParam,
|
|
} = dataArg;
|
|
|
|
const limit = limitParam || 100;
|
|
const offset = offsetParam || 0;
|
|
const startDate = startDateStr ? new Date(startDateStr) : undefined;
|
|
const endDate = endDateStr ? new Date(endDateStr) : undefined;
|
|
|
|
// Determine actor filter based on permissions
|
|
let actorId: string | undefined;
|
|
|
|
if (dataArg.identity.isSystemAdmin) {
|
|
// System admins can see all
|
|
actorId = dataArg.actorId;
|
|
} else if (organizationId) {
|
|
// Check if user can manage this org
|
|
const canManage = await this.permissionService.canManageOrganization(
|
|
dataArg.identity.userId,
|
|
organizationId,
|
|
);
|
|
if (!canManage) {
|
|
// User can only see their own actions in this org
|
|
actorId = dataArg.identity.userId;
|
|
}
|
|
} else {
|
|
// Non-admins without org filter can only see their own actions
|
|
actorId = dataArg.identity.userId;
|
|
}
|
|
|
|
const result = await AuditLog.query({
|
|
actorId,
|
|
organizationId,
|
|
repositoryId,
|
|
resourceType: resourceType as any,
|
|
action: actions as any[],
|
|
success,
|
|
startDate,
|
|
endDate,
|
|
limit,
|
|
offset,
|
|
});
|
|
|
|
return {
|
|
logs: result.logs.map((log) => ({
|
|
id: log.id,
|
|
actorId: log.actorId,
|
|
actorType: log.actorType as interfaces.data.IAuditEntry['actorType'],
|
|
action: log.action as interfaces.data.TAuditAction,
|
|
resourceType: log.resourceType as interfaces.data.TAuditResourceType,
|
|
resourceId: log.resourceId,
|
|
resourceName: log.resourceName,
|
|
organizationId: log.organizationId,
|
|
repositoryId: log.repositoryId,
|
|
success: log.success,
|
|
errorCode: log.errorCode,
|
|
timestamp: log.timestamp instanceof Date ? log.timestamp.toISOString() : String(log.timestamp),
|
|
metadata: log.metadata || {},
|
|
})),
|
|
total: result.total,
|
|
limit,
|
|
offset,
|
|
};
|
|
} catch (error) {
|
|
if (error instanceof plugins.typedrequest.TypedResponseError) throw error;
|
|
throw new plugins.typedrequest.TypedResponseError('Failed to query audit logs');
|
|
}
|
|
},
|
|
),
|
|
);
|
|
}
|
|
}
|