Spaces:
Paused
Paused
| import { prisma } from '../../database/prisma.js'; | |
| import type { | |
| SecuritySearchTemplate, | |
| SearchHistoryEntry, | |
| SecurityActivityEvent, | |
| } from './securityTypes.js'; | |
| export async function getSecurityTemplates(): Promise<SecuritySearchTemplate[]> { | |
| const rows = await prisma.securitySearchTemplate.findMany({ | |
| orderBy: { createdAt: 'desc' }, | |
| }); | |
| return rows.map(row => ({ | |
| id: row.id, | |
| name: row.name, | |
| description: row.description, | |
| query: row.query, | |
| severity: row.severity as SecuritySearchTemplate['severity'], | |
| timeframe: row.timeframe, | |
| sources: (row.sources as string[]) ?? [], | |
| createdAt: row.createdAt.toISOString(), | |
| })); | |
| } | |
| export async function recordSearchHistory(entry: Omit<SearchHistoryEntry, 'ranAt'> & { ranAt?: string }): Promise<SearchHistoryEntry> { | |
| const created = await prisma.securitySearchHistory.create({ | |
| data: { | |
| id: entry.id, | |
| query: entry.query, | |
| severity: entry.severity, | |
| timeframe: entry.timeframe, | |
| sources: entry.sources, | |
| results: entry.results, | |
| latencyMs: entry.latencyMs, | |
| createdAt: entry.ranAt ? new Date(entry.ranAt) : undefined, | |
| }, | |
| }); | |
| return { | |
| ...entry, | |
| ranAt: created.createdAt.toISOString(), | |
| }; | |
| } | |
| export async function getSearchHistory(limit = 6): Promise<SearchHistoryEntry[]> { | |
| const rows = await prisma.securitySearchHistory.findMany({ | |
| orderBy: { createdAt: 'desc' }, | |
| take: limit, | |
| }); | |
| return rows.map(row => ({ | |
| id: row.id, | |
| query: row.query, | |
| severity: row.severity, | |
| timeframe: row.timeframe, | |
| sources: (row.sources as string[]) ?? [], | |
| results: row.results, | |
| latencyMs: row.latencyMs, | |
| ranAt: row.createdAt.toISOString(), | |
| })); | |
| } | |
| export async function persistActivityEvent(event: SecurityActivityEvent): Promise<void> { | |
| await prisma.securityActivityEvent.upsert({ | |
| where: { id: event.id }, | |
| update: { | |
| title: event.title, | |
| description: event.description, | |
| category: event.category, | |
| severity: event.severity, | |
| source: event.source, | |
| rule: event.rule ?? null, | |
| channel: event.channel, | |
| payload: event.payload as any, | |
| createdAt: event.createdAt ? new Date(event.createdAt) : undefined, | |
| acknowledged: event.acknowledged ?? false, | |
| }, | |
| create: { | |
| id: event.id, | |
| title: event.title, | |
| description: event.description, | |
| category: event.category, | |
| severity: event.severity, | |
| source: event.source, | |
| rule: event.rule ?? null, | |
| channel: event.channel, | |
| payload: event.payload as any, | |
| createdAt: event.createdAt ? new Date(event.createdAt) : undefined, | |
| acknowledged: event.acknowledged ?? false, | |
| }, | |
| }); | |
| } | |
| interface ActivityFilter { | |
| severity?: string; | |
| category?: string; | |
| limit?: number; | |
| } | |
| export async function listActivityEvents(filter: ActivityFilter = {}): Promise<SecurityActivityEvent[]> { | |
| const where: any = {}; | |
| if (filter.severity && filter.severity !== 'all') { | |
| where.severity = filter.severity; | |
| } | |
| if (filter.category && filter.category !== 'all') { | |
| where.category = filter.category; | |
| } | |
| const rows = await prisma.securityActivityEvent.findMany({ | |
| where, | |
| orderBy: { createdAt: 'desc' }, | |
| take: filter.limit ?? 25, | |
| }); | |
| return rows.map(row => ({ | |
| id: row.id, | |
| title: row.title, | |
| description: row.description, | |
| category: row.category as SecurityActivityEvent['category'], | |
| severity: row.severity as SecurityActivityEvent['severity'], | |
| source: row.source, | |
| rule: row.rule ?? undefined, | |
| channel: row.channel as SecurityActivityEvent['channel'], | |
| payload: row.payload as Record<string, unknown> | undefined, | |
| createdAt: row.createdAt.toISOString(), | |
| acknowledged: row.acknowledged, | |
| })); | |
| } | |
| export async function setActivityAcknowledged(id: string, acknowledged: boolean): Promise<SecurityActivityEvent | null> { | |
| try { | |
| const updated = await prisma.securityActivityEvent.update({ | |
| where: { id }, | |
| data: { acknowledged }, | |
| }); | |
| return { | |
| id: updated.id, | |
| title: updated.title, | |
| description: updated.description, | |
| category: updated.category as SecurityActivityEvent['category'], | |
| severity: updated.severity as SecurityActivityEvent['severity'], | |
| source: updated.source, | |
| rule: updated.rule ?? undefined, | |
| channel: updated.channel as SecurityActivityEvent['channel'], | |
| payload: updated.payload as Record<string, unknown> | undefined, | |
| createdAt: updated.createdAt.toISOString(), | |
| acknowledged: updated.acknowledged, | |
| }; | |
| } catch { | |
| return null; | |
| } | |
| } | |
| export async function getWidgetPermissions(widgetId: string): Promise<any[]> { | |
| return prisma.widgetPermission.findMany({ | |
| where: { widgetId }, | |
| }); | |
| } | |
| export async function checkWidgetAccess(widgetId: string, resourceType: string, requiredLevel: 'read' | 'write'): Promise<boolean> { | |
| const row = await prisma.widgetPermission.findUnique({ | |
| where: { widgetId_resourceType: { widgetId, resourceType } }, | |
| }); | |
| const levels = { none: 0, read: 1, write: 2 }; | |
| if (row && row.override) { | |
| return levels[row.accessLevel as keyof typeof levels] >= levels[requiredLevel]; | |
| } | |
| const defaultRow = await prisma.widgetPermission.findUnique({ | |
| where: { widgetId_resourceType: { widgetId: 'SYSTEM_DEFAULT', resourceType } }, | |
| }); | |
| const defaultLevel = defaultRow ? defaultRow.accessLevel : 'read'; | |
| return levels[defaultLevel as keyof typeof levels] >= levels[requiredLevel]; | |
| } | |
| export async function setWidgetPermission(widgetId: string, resourceType: string, accessLevel: 'none' | 'read' | 'write', override: boolean = false): Promise<void> { | |
| await prisma.widgetPermission.upsert({ | |
| where: { widgetId_resourceType: { widgetId, resourceType } }, | |
| update: { accessLevel, override }, | |
| create: { widgetId, resourceType, accessLevel, override }, | |
| }); | |
| } | |
| export async function setPlatformDefault(resourceType: string, accessLevel: 'none' | 'read' | 'write'): Promise<void> { | |
| await prisma.widgetPermission.upsert({ | |
| where: { widgetId_resourceType: { widgetId: 'SYSTEM_DEFAULT', resourceType } }, | |
| update: { accessLevel, override: false }, | |
| create: { widgetId: 'SYSTEM_DEFAULT', resourceType, accessLevel, override: false }, | |
| }); | |
| } | |