Refactor suspicious artifact data structures, enhance eliminated state tracking, and update UI rendering for eliminated items. Add JSON marshal/unmarshal support for Binary and Directory types.
This commit is contained in:
@@ -22,16 +22,17 @@ type DeletedMsg struct {
|
||||
}
|
||||
|
||||
type DetailViewModel struct {
|
||||
typeKey string
|
||||
index int
|
||||
data suspicious.Suspicious
|
||||
typeKey string
|
||||
index int
|
||||
data suspicious.Suspicious
|
||||
eliminated map[string]map[int]bool
|
||||
// When modal* != "", show modal and require ESC to dismiss
|
||||
modalErr string
|
||||
modalWarn string
|
||||
}
|
||||
|
||||
func NewDetailView(typeKey string, index int, data suspicious.Suspicious) DetailViewModel {
|
||||
return DetailViewModel{typeKey: typeKey, index: index, data: data}
|
||||
func NewDetailView(typeKey string, index int, data suspicious.Suspicious, eliminated map[string]map[int]bool) DetailViewModel {
|
||||
return DetailViewModel{typeKey: typeKey, index: index, data: data, eliminated: eliminated}
|
||||
}
|
||||
|
||||
func (m DetailViewModel) Init() tea.Cmd { return nil }
|
||||
@@ -60,8 +61,22 @@ func (m DetailViewModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
}
|
||||
|
||||
func (m DetailViewModel) View() string {
|
||||
title := lipgloss.NewStyle().Bold(true).Render("Details — press ! to eliminate, Left to go back, q to quit")
|
||||
isEliminated := m.eliminated[m.typeKey] != nil && m.eliminated[m.typeKey][m.index]
|
||||
|
||||
var title string
|
||||
if isEliminated {
|
||||
title = lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("10")).Render("Details — ELIMINATED — Left to go back, q to quit")
|
||||
} else {
|
||||
title = lipgloss.NewStyle().Bold(true).Render("Details — press ! to eliminate, Left to go back, q to quit")
|
||||
}
|
||||
|
||||
body := m.renderDetails()
|
||||
|
||||
// Apply green styling to body if eliminated
|
||||
if isEliminated {
|
||||
body = lipgloss.NewStyle().Foreground(lipgloss.Color("10")).Render(body)
|
||||
}
|
||||
|
||||
view := title + "\n\n" + body
|
||||
if m.modalWarn != "" {
|
||||
modal := lipgloss.NewStyle().Padding(1, 2).Foreground(lipgloss.Color("214")).Border(lipgloss.RoundedBorder()).Render("Warning:\n" + m.modalWarn + "\n\nPress ESC to dismiss")
|
||||
@@ -77,24 +92,45 @@ func (m DetailViewModel) View() string {
|
||||
func (m DetailViewModel) renderDetails() string {
|
||||
switch m.typeKey {
|
||||
case "autoruns":
|
||||
if m.index >= len(m.data.AutoRuns) {
|
||||
return "Item no longer available"
|
||||
}
|
||||
ar := m.data.AutoRuns[m.index]
|
||||
return fmt.Sprintf("Type: %s\nEntry: %s\nLaunch: %s\nLocation: %s\nImage: %s\nArgs: %s\nMD5: %s\nSHA1: %s\nSHA256: %s", ar.Type, ar.Entry, ar.LaunchString, ar.Location, ar.ImagePath, ar.Arguments, ar.MD5, ar.SHA1, ar.SHA256)
|
||||
case "binaries":
|
||||
if m.index >= len(m.data.Binaries) {
|
||||
return "Item no longer available"
|
||||
}
|
||||
b := m.data.Binaries[m.index]
|
||||
return fmt.Sprintf("Binary: %s\nAction: delete file", b)
|
||||
return fmt.Sprintf("Binary: %s\nAction: delete file", b.Path)
|
||||
case "connections":
|
||||
if m.index >= len(m.data.OutboundConnections) {
|
||||
return "Item no longer available"
|
||||
}
|
||||
c := m.data.OutboundConnections[m.index]
|
||||
return fmt.Sprintf("Local: %s\nRemote: %s\nHost: %s\nState: %s\nPID: %s\nProcess: %s\nAction: add firewall block (placeholder)", c.LocalAddr, c.RemoteAddr, c.RemoteHost, c.State, c.PID, c.Process)
|
||||
case "directories":
|
||||
if m.index >= len(m.data.Directories) {
|
||||
return "Item no longer available"
|
||||
}
|
||||
d := m.data.Directories[m.index]
|
||||
return fmt.Sprintf("Directory: %s\nAction: delete recursively", d)
|
||||
return fmt.Sprintf("Directory: %s\nAction: delete recursively", d.Path)
|
||||
case "processes":
|
||||
if m.index >= len(m.data.Processes) {
|
||||
return "Item no longer available"
|
||||
}
|
||||
p := m.data.Processes[m.index]
|
||||
return fmt.Sprintf("Name: %s\nPID: %d\nPPID: %d\nParent: %s\nArgs: %s\nCreated: %s\nPath: %s\nAction: stop then delete (placeholder)", p.Name, p.PID, p.PPID, p.Parent, p.Args, p.Created, p.Path)
|
||||
case "scheduledTasks":
|
||||
if m.index >= len(m.data.ScheduledTasks) {
|
||||
return "Item no longer available"
|
||||
}
|
||||
t := m.data.ScheduledTasks[m.index]
|
||||
return fmt.Sprintf("Name: %s\nAuthor: %s\nState: %s\nEnabled: %v\nLastResult: %s\nNextRun: %s\nLastRun: %s\nPath: %s\nAction: disable then delete (placeholder)", t.Name, t.Author, t.State, t.Enabled, t.LastResult, t.NextRun, t.LastRun, t.Path)
|
||||
case "services":
|
||||
if m.index >= len(m.data.Services) {
|
||||
return "Item no longer available"
|
||||
}
|
||||
s := m.data.Services[m.index]
|
||||
return fmt.Sprintf("Name: %s\nDisplay: %s\nType: %s\nStartType: %s\nBinPath: %s\nStartName: %s\nDescription: %s\nAction: stop then delete (placeholder)", s.Name, s.DisplayName, s.ServiceType, s.StartType, s.BinaryPathName, s.ServiceStartName, s.Description)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user