Skip to content

Separate timeline event summaries from additional notes #286

Description

@Th4nat0s

Problem

Case_Timeline_Event in app/db_class/db.py currently has one required description field. The create/edit routes in app/case/case.py, core methods in app/case/CaseCore.py, and app/static/js/case/timeline_view.js use that field for both the concise event identity and any supporting detail.

The timeline form labels description as Description and renders it in a textarea. TimelineJS then uses the same value as both headline and body text. This encourages long summaries, duplicates content in the graphical view, and makes the event list harder to scan.

Analysts need two distinct concepts:

  • Event: a short one-line statement, for example Tartempion logged in.
  • Additional Note: optional multiline context, for example evidence from Windows event 4624, the domain controller, session start, and affected host.

MISP import currently combines [MISP] <object name> and all attribute details into description, then parses that string in the frontend to derive a headline. Structured fields would remove this coupling for new imports.

Proposed approach

Keep the existing required DB and JSON field description for backward compatibility, but relabel it as Event in the UI and render it with a single-line text input. Renaming the stored/API field would break existing consumers and is not required for the requested user-facing terminology.

Add a nullable multiline additional_note field to Case_Timeline_Event through an Alembic migration. Include it in to_json(), core create/edit methods, and timeline request handling.

Creation behavior:

  • description remains required and represents the Event summary.
  • additional_note is optional and defaults to null or empty.

Edit behavior must distinguish an omitted additional_note key from an explicitly empty value. Omission by an older client preserves the existing note; an explicit empty or null value clears it.

Update app/static/js/case/timeline_view.js so forms use a one-line Event input and a multiline Additional Note textarea. The table displays separate Event and Additional Note content. TimelineJS uses Event as headline and Additional Note as body text without duplicating the headline when no note exists.

For new MISP imports, store the concise MISP object identity in description and attribute details in additional_note. Preserve existing imported rows without attempting a risky content-splitting migration.

Treat both fields as untrusted text. Fully escape text before adding line-break markup or sanitize the constructed TimelineJS HTML with the already-loaded DOMPurify. Rendering must not interpret analyst content as HTML.

This requires model, migration, core, route, serialization, frontend, tests, and documentation changes. No external dependency or deployment configuration change is required.

Scope

  • Add nullable additional_note storage to Case_Timeline_Event.
  • Add Alembic upgrade and downgrade paths compatible with PostgreSQL and SQLite.
  • Preserve description as the required internal and JSON field for compatibility.
  • Relabel Description as Event in timeline create/edit/list UI.
  • Replace the Event textarea with a single-line input.
  • Add optional multiline Additional Note controls for creation and editing.
  • Serialize, create, update, preserve, and explicitly clear additional_note.
  • Render Event as TimelineJS headline and Additional Note as body content.
  • Preserve multiline formatting while safely escaping or sanitizing both fields.
  • Split new MISP imports into concise Event and detailed Additional Note values.
  • Keep existing timeline rows unchanged; no heuristic backfill of old descriptions.
  • Add automated backend tests for migration defaults, serialization, create/edit behavior, omission compatibility, explicit clearing, and MISP import.
  • Add frontend regression coverage where supported; otherwise document focused manual verification of forms, table, TimelineJS, multiline display, and malicious markup.
  • Update doc/technical-specifications.md and relevant user documentation.
  • Keep rich-text or Markdown editing, attachments, source records, arbitrary size limits, and API field renaming outside scope.

Acceptance criteria

  • Create form shows required Event as a one-line input and optional Additional Note as a multiline textarea.
  • An event can be created with description: "Tartempion logged in" and a multiline additional_note.
  • An event can be created without Additional Note.
  • Edit form loads and saves both values.
  • An edit request that omits additional_note preserves its existing value for backward compatibility.
  • An edit request with explicit null or empty additional_note clears the note.
  • Empty or whitespace-only Event remains rejected server-side.
  • Non-string values for Event or Additional Note are rejected with a controlled client error and no partial update.
  • Event table presents concise Event and Additional Note as distinct content.
  • TimelineJS uses Event as headline and Additional Note as body, without repeating Event when no note exists.
  • Line breaks in Additional Note remain visible.
  • HTML and script payloads in either field render as inert text in both Vue and TimelineJS views.
  • New MISP imports place object identity in Event and attribute details in Additional Note while preserving the MISP icon and linkage.
  • Existing events remain readable and editable with additional_note null after migration.
  • Existing date parsing, sorting, normalized date display, event links, sources, deletion, and permissions remain unchanged.
  • Automated tests cover required/optional values, old-client omission, explicit clearing, multiline serialization, MISP import, and XSS-safe rendering behavior.
  • Migration upgrade preserves all existing descriptions. Downgrade behavior documents that newly stored Additional Notes are lost unless backed up first.
  • Technical and user documentation use Event and Additional Note terminology consistently.

Dependencies

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions