mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Threat Hunting Investigations] Migrate all timeline routes to OpenAPI types (#190238)
## Summary fixes: https://github.com/elastic/security-team/issues/10235 fixes: https://github.com/elastic/security-team/issues/10237 This is the final PR for migrating over all timeline-related schemas and types to the new generated zod schemas from our OpenAPI specs. (see https://github.com/elastic/security-team/issues/10110) On top of moving to the new schemas/types, this PR also cleans up usage of now outdated types. I'm aware of the size of this PR but rest assured, the changes are easy to review and for most teams, only a handful of files need to be reviewed: ```markdown ### elastic/security-defend-workflows * x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_solution_integrations.ts ### elastic/security-detection-rule-management * x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/get_prebuilt_rules_and_timelines_status_route.ts * x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/perform_timelines_installation.ts ### elastic/security-detections-response * x-pack/test/security_solution_cypress/cypress/objects/timeline.ts ### elastic/security-engineering-productivity * x-pack/test/security_solution_cypress/cypress/objects/timeline.ts * x-pack/test/security_solution_cypress/cypress/tasks/api_calls/timelines.ts ``` ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
7fd3317423
commit
00789609ad
107 changed files with 2042 additions and 2689 deletions
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
|
@ -1532,6 +1532,7 @@ x-pack/test/security_solution_api_integration/test_suites/sources @elastic/secur
|
|||
x-pack/test/security_solution_cypress/cypress/screens/expandable_flyout @elastic/security-threat-hunting-investigations
|
||||
x-pack/test/security_solution_cypress/cypress/tasks/expandable_flyout @elastic/security-threat-hunting-investigations
|
||||
|
||||
/x-pack/plugins/security_solution/common/timelines @elastic/security-threat-hunting-investigations
|
||||
/x-pack/plugins/security_solution/public/common/components/alerts_viewer @elastic/security-threat-hunting-investigations
|
||||
/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_action @elastic/security-threat-hunting-investigations
|
||||
/x-pack/plugins/security_solution/public/common/components/event_details @elastic/security-threat-hunting-investigations
|
||||
|
|
|
@ -16356,19 +16356,21 @@ paths:
|
|||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
oneOf:
|
||||
- type: object
|
||||
properties:
|
||||
getOneTimeline:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_TimelineResponse
|
||||
nullable: true
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
getOneTimeline:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_TimelineResponse
|
||||
required:
|
||||
- getOneTimeline
|
||||
required:
|
||||
- getOneTimeline
|
||||
required:
|
||||
- data
|
||||
- data
|
||||
- additionalProperties: false
|
||||
type: object
|
||||
description: Indicates that the (template) Timeline was found and returned.
|
||||
summary: Get Timeline or Timeline template details
|
||||
tags:
|
||||
|
@ -16405,23 +16407,8 @@ paths:
|
|||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_TimelineResponse
|
||||
required:
|
||||
- timeline
|
||||
required:
|
||||
- persistTimeline
|
||||
required:
|
||||
- data
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_PersistTimelineResponse
|
||||
description: >-
|
||||
Indicates that the draft Timeline was successfully created. In the
|
||||
event the user already has a draft Timeline, the existing draft
|
||||
|
@ -16483,21 +16470,8 @@ paths:
|
|||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_TimelineResponse
|
||||
required:
|
||||
- persistTimeline
|
||||
required:
|
||||
- data
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_PersistTimelineResponse
|
||||
description: Indicates the Timeline was successfully created.
|
||||
'405':
|
||||
content:
|
||||
|
@ -16514,6 +16488,37 @@ paths:
|
|||
tags:
|
||||
- Security Timeline API
|
||||
- access:securitySolution
|
||||
/api/timeline/_copy:
|
||||
get:
|
||||
description: |
|
||||
Copies and returns a timeline or timeline template.
|
||||
operationId: CopyTimeline
|
||||
requestBody:
|
||||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_SavedTimeline'
|
||||
timelineIdToCopy:
|
||||
type: string
|
||||
required:
|
||||
- timeline
|
||||
- timelineIdToCopy
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_PersistTimelineResponse
|
||||
description: Indicates that the timeline has been successfully copied.
|
||||
summary: Copies timeline or timeline template
|
||||
tags:
|
||||
- Security Timeline API
|
||||
- access:securitySolution
|
||||
/api/timeline/_draft:
|
||||
get:
|
||||
description: >-
|
||||
|
@ -16532,23 +16537,8 @@ paths:
|
|||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_TimelineResponse
|
||||
required:
|
||||
- timeline
|
||||
required:
|
||||
- persistTimeline
|
||||
required:
|
||||
- data
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_PersistTimelineResponse
|
||||
description: Indicates that the draft Timeline was successfully retrieved.
|
||||
'403':
|
||||
content:
|
||||
|
@ -16610,23 +16600,8 @@ paths:
|
|||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_TimelineResponse
|
||||
required:
|
||||
- timeline
|
||||
required:
|
||||
- persistTimeline
|
||||
required:
|
||||
- data
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_PersistTimelineResponse
|
||||
description: >-
|
||||
Indicates that the draft Timeline was successfully created. In the
|
||||
event the user already has a draft Timeline, the existing draft
|
||||
|
@ -16782,28 +16757,14 @@ paths:
|
|||
schema:
|
||||
type: object
|
||||
properties:
|
||||
file:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Security_Timeline_API_Readable'
|
||||
- type: object
|
||||
properties:
|
||||
hapi:
|
||||
type: object
|
||||
properties:
|
||||
filename:
|
||||
type: string
|
||||
headers:
|
||||
type: object
|
||||
isImmutable:
|
||||
enum:
|
||||
- 'true'
|
||||
- 'false'
|
||||
type: string
|
||||
required:
|
||||
- filename
|
||||
- headers
|
||||
required:
|
||||
- hapi
|
||||
file: {}
|
||||
isImmutable:
|
||||
enum:
|
||||
- 'true'
|
||||
- 'false'
|
||||
type: string
|
||||
required:
|
||||
- file
|
||||
description: The Timelines to import as a readable stream.
|
||||
required: true
|
||||
responses:
|
||||
|
@ -16811,13 +16772,8 @@ paths:
|
|||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_ImportTimelineResult
|
||||
required:
|
||||
- data
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_ImportTimelineResult
|
||||
description: Indicates the import of Timelines was successful.
|
||||
'400':
|
||||
content:
|
||||
|
@ -16876,7 +16832,9 @@ paths:
|
|||
properties:
|
||||
prepackagedTimelines:
|
||||
items:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_SavedTimeline'
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_TimelineSavedToReturnObject
|
||||
nullable: true
|
||||
type: array
|
||||
timelinesToInstall:
|
||||
items:
|
||||
|
@ -16899,13 +16857,8 @@ paths:
|
|||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_ImportTimelineResult
|
||||
required:
|
||||
- data
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_ImportTimelineResult
|
||||
description: Indicates the installation of prepackaged Timelines was successful.
|
||||
'500':
|
||||
content:
|
||||
|
@ -16943,19 +16896,16 @@ paths:
|
|||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
oneOf:
|
||||
- type: object
|
||||
properties:
|
||||
getOneTimeline:
|
||||
data:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_TimelineResponse
|
||||
nullable: true
|
||||
#/components/schemas/Security_Timeline_API_ResolvedTimeline
|
||||
required:
|
||||
- getOneTimeline
|
||||
required:
|
||||
- data
|
||||
- data
|
||||
- additionalProperties: false
|
||||
type: object
|
||||
description: The (template) Timeline has been found
|
||||
'400':
|
||||
description: The request is missing parameters
|
||||
|
@ -17024,36 +16974,26 @@ paths:
|
|||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
customTemplateTimelineCount:
|
||||
type: number
|
||||
defaultTimelineCount:
|
||||
type: number
|
||||
elasticTemplateTimelineCount:
|
||||
type: number
|
||||
favoriteCount:
|
||||
type: number
|
||||
templateTimelineCount:
|
||||
type: number
|
||||
timelines:
|
||||
items:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_TimelineResponse
|
||||
type: array
|
||||
totalCount:
|
||||
type: number
|
||||
required:
|
||||
- timelines
|
||||
- totalCount
|
||||
- defaultTimelineCount
|
||||
- templateTimelineCount
|
||||
- favoriteCount
|
||||
- elasticTemplateTimelineCount
|
||||
- customTemplateTimelineCount
|
||||
customTemplateTimelineCount:
|
||||
type: number
|
||||
defaultTimelineCount:
|
||||
type: number
|
||||
elasticTemplateTimelineCount:
|
||||
type: number
|
||||
favoriteCount:
|
||||
type: number
|
||||
templateTimelineCount:
|
||||
type: number
|
||||
timeline:
|
||||
items:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_TimelineResponse
|
||||
type: array
|
||||
totalCount:
|
||||
type: number
|
||||
required:
|
||||
- data
|
||||
- timeline
|
||||
- totalCount
|
||||
description: Indicates that the (template) Timelines were found and returned.
|
||||
'400':
|
||||
content:
|
||||
|
@ -31335,30 +31275,39 @@ components:
|
|||
type: object
|
||||
properties:
|
||||
aggregatable:
|
||||
nullable: true
|
||||
type: boolean
|
||||
category:
|
||||
nullable: true
|
||||
type: string
|
||||
columnHeaderType:
|
||||
nullable: true
|
||||
type: string
|
||||
description:
|
||||
nullable: true
|
||||
type: string
|
||||
example:
|
||||
oneOf:
|
||||
- type: string
|
||||
- type: number
|
||||
nullable: true
|
||||
type: string
|
||||
id:
|
||||
nullable: true
|
||||
type: string
|
||||
indexes:
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
name:
|
||||
nullable: true
|
||||
type: string
|
||||
placeholder:
|
||||
nullable: true
|
||||
type: string
|
||||
searchable:
|
||||
nullable: true
|
||||
type: boolean
|
||||
type:
|
||||
nullable: true
|
||||
type: string
|
||||
Security_Timeline_API_DataProviderQueryMatch:
|
||||
type: object
|
||||
|
@ -31380,6 +31329,10 @@ components:
|
|||
type: string
|
||||
queryMatch:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_QueryMatchResult'
|
||||
nullable: true
|
||||
type:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_DataProviderType'
|
||||
nullable: true
|
||||
Security_Timeline_API_DataProviderResult:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -31467,41 +31420,59 @@ components:
|
|||
type: object
|
||||
properties:
|
||||
exists:
|
||||
type: boolean
|
||||
nullable: true
|
||||
type: string
|
||||
match_all:
|
||||
nullable: true
|
||||
type: string
|
||||
meta:
|
||||
nullable: true
|
||||
type: object
|
||||
properties:
|
||||
alias:
|
||||
nullable: true
|
||||
type: string
|
||||
controlledBy:
|
||||
nullable: true
|
||||
type: string
|
||||
disabled:
|
||||
nullable: true
|
||||
type: boolean
|
||||
field:
|
||||
nullable: true
|
||||
type: string
|
||||
formattedValue:
|
||||
nullable: true
|
||||
type: string
|
||||
index:
|
||||
nullable: true
|
||||
type: string
|
||||
key:
|
||||
nullable: true
|
||||
type: string
|
||||
negate:
|
||||
nullable: true
|
||||
type: boolean
|
||||
params:
|
||||
nullable: true
|
||||
type: string
|
||||
type:
|
||||
nullable: true
|
||||
type: string
|
||||
value:
|
||||
nullable: true
|
||||
type: string
|
||||
missing:
|
||||
nullable: true
|
||||
type: string
|
||||
query:
|
||||
nullable: true
|
||||
type: string
|
||||
range:
|
||||
nullable: true
|
||||
type: string
|
||||
script:
|
||||
nullable: true
|
||||
type: string
|
||||
Security_Timeline_API_GetNotesResult:
|
||||
type: object
|
||||
|
@ -31566,6 +31537,12 @@ components:
|
|||
version:
|
||||
nullable: true
|
||||
type: string
|
||||
required:
|
||||
- savedObjectId
|
||||
- version
|
||||
- pinnedEventIds
|
||||
- eventNotes
|
||||
- globalNotes
|
||||
Security_Timeline_API_Note:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Security_Timeline_API_BareNote'
|
||||
|
@ -31586,6 +31563,23 @@ components:
|
|||
#/components/schemas/Security_Timeline_API_PinnedEventBaseResponseBody
|
||||
- nullable: true
|
||||
type: object
|
||||
Security_Timeline_API_PersistTimelineResponse:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_TimelineResponse'
|
||||
required:
|
||||
- timeline
|
||||
required:
|
||||
- persistTimeline
|
||||
required:
|
||||
- data
|
||||
Security_Timeline_API_PinnedEvent:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Security_Timeline_API_BarePinnedEvent'
|
||||
|
@ -31623,34 +31617,29 @@ components:
|
|||
nullable: true
|
||||
type: string
|
||||
value:
|
||||
nullable: true
|
||||
type: string
|
||||
Security_Timeline_API_Readable:
|
||||
oneOf:
|
||||
- nullable: true
|
||||
type: string
|
||||
- items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
Security_Timeline_API_ResolvedTimeline:
|
||||
type: object
|
||||
properties:
|
||||
_data:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
_encoding:
|
||||
alias_purpose:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_SavedObjectResolveAliasPurpose
|
||||
alias_target_id:
|
||||
type: string
|
||||
_events:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
_eventsCount:
|
||||
type: number
|
||||
_maxListeners:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
_position:
|
||||
type: number
|
||||
_read:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
_readableState:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
readable:
|
||||
type: boolean
|
||||
outcome:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_SavedObjectResolveOutcome'
|
||||
timeline:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_TimelineSavedToReturnObject
|
||||
required:
|
||||
- timeline
|
||||
- outcome
|
||||
Security_Timeline_API_ResponseNote:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -31685,6 +31674,17 @@ components:
|
|||
- threat_match
|
||||
- zeek
|
||||
type: string
|
||||
Security_Timeline_API_SavedObjectResolveAliasPurpose:
|
||||
enum:
|
||||
- savedObjectConversion
|
||||
- savedObjectImport
|
||||
type: string
|
||||
Security_Timeline_API_SavedObjectResolveOutcome:
|
||||
enum:
|
||||
- exactMatch
|
||||
- aliasMatch
|
||||
- conflict
|
||||
type: string
|
||||
Security_Timeline_API_SavedTimeline:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -31713,12 +31713,16 @@ components:
|
|||
properties:
|
||||
end:
|
||||
oneOf:
|
||||
- type: string
|
||||
- type: number
|
||||
- nullable: true
|
||||
type: string
|
||||
- nullable: true
|
||||
type: number
|
||||
start:
|
||||
oneOf:
|
||||
- type: string
|
||||
- type: number
|
||||
- nullable: true
|
||||
type: string
|
||||
- nullable: true
|
||||
type: number
|
||||
description:
|
||||
nullable: true
|
||||
type: string
|
||||
|
@ -31808,6 +31812,18 @@ components:
|
|||
updatedBy:
|
||||
nullable: true
|
||||
type: string
|
||||
Security_Timeline_API_SavedTimelineWithSavedObjectId:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Security_Timeline_API_SavedTimeline'
|
||||
- type: object
|
||||
properties:
|
||||
savedObjectId:
|
||||
type: string
|
||||
version:
|
||||
type: string
|
||||
required:
|
||||
- savedObjectId
|
||||
- version
|
||||
Security_Timeline_API_SerializedFilterQueryResult:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -31857,27 +31873,64 @@ components:
|
|||
Security_Timeline_API_TimelineResponse:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Security_Timeline_API_SavedTimeline'
|
||||
- $ref: >-
|
||||
#/components/schemas/Security_Timeline_API_SavedTimelineWithSavedObjectId
|
||||
- type: object
|
||||
properties:
|
||||
eventIdToNoteIds:
|
||||
items:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_Note'
|
||||
nullable: true
|
||||
type: array
|
||||
noteIds:
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
notes:
|
||||
items:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_Note'
|
||||
nullable: true
|
||||
type: array
|
||||
pinnedEventIds:
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
pinnedEventsSaveObject:
|
||||
items:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_PinnedEvent'
|
||||
nullable: true
|
||||
type: array
|
||||
Security_Timeline_API_TimelineSavedToReturnObject:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Security_Timeline_API_SavedTimeline'
|
||||
- type: object
|
||||
properties:
|
||||
eventIdToNoteIds:
|
||||
items:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_Note'
|
||||
nullable: true
|
||||
type: array
|
||||
noteIds:
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
notes:
|
||||
items:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_Note'
|
||||
nullable: true
|
||||
type: array
|
||||
pinnedEventIds:
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
pinnedEventsSaveObject:
|
||||
items:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_PinnedEvent'
|
||||
nullable: true
|
||||
type: array
|
||||
savedObjectId:
|
||||
type: string
|
||||
|
|
|
@ -20445,19 +20445,21 @@ paths:
|
|||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
oneOf:
|
||||
- type: object
|
||||
properties:
|
||||
getOneTimeline:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_TimelineResponse
|
||||
nullable: true
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
getOneTimeline:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_TimelineResponse
|
||||
required:
|
||||
- getOneTimeline
|
||||
required:
|
||||
- getOneTimeline
|
||||
required:
|
||||
- data
|
||||
- data
|
||||
- additionalProperties: false
|
||||
type: object
|
||||
description: Indicates that the (template) Timeline was found and returned.
|
||||
summary: Get Timeline or Timeline template details
|
||||
tags:
|
||||
|
@ -20494,23 +20496,8 @@ paths:
|
|||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_TimelineResponse
|
||||
required:
|
||||
- timeline
|
||||
required:
|
||||
- persistTimeline
|
||||
required:
|
||||
- data
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_PersistTimelineResponse
|
||||
description: >-
|
||||
Indicates that the draft Timeline was successfully created. In the
|
||||
event the user already has a draft Timeline, the existing draft
|
||||
|
@ -20572,21 +20559,8 @@ paths:
|
|||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_TimelineResponse
|
||||
required:
|
||||
- persistTimeline
|
||||
required:
|
||||
- data
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_PersistTimelineResponse
|
||||
description: Indicates the Timeline was successfully created.
|
||||
'405':
|
||||
content:
|
||||
|
@ -20603,6 +20577,37 @@ paths:
|
|||
tags:
|
||||
- Security Timeline API
|
||||
- access:securitySolution
|
||||
/api/timeline/_copy:
|
||||
get:
|
||||
description: |
|
||||
Copies and returns a timeline or timeline template.
|
||||
operationId: CopyTimeline
|
||||
requestBody:
|
||||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_SavedTimeline'
|
||||
timelineIdToCopy:
|
||||
type: string
|
||||
required:
|
||||
- timeline
|
||||
- timelineIdToCopy
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_PersistTimelineResponse
|
||||
description: Indicates that the timeline has been successfully copied.
|
||||
summary: Copies timeline or timeline template
|
||||
tags:
|
||||
- Security Timeline API
|
||||
- access:securitySolution
|
||||
/api/timeline/_draft:
|
||||
get:
|
||||
description: >-
|
||||
|
@ -20621,23 +20626,8 @@ paths:
|
|||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_TimelineResponse
|
||||
required:
|
||||
- timeline
|
||||
required:
|
||||
- persistTimeline
|
||||
required:
|
||||
- data
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_PersistTimelineResponse
|
||||
description: Indicates that the draft Timeline was successfully retrieved.
|
||||
'403':
|
||||
content:
|
||||
|
@ -20699,23 +20689,8 @@ paths:
|
|||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_TimelineResponse
|
||||
required:
|
||||
- timeline
|
||||
required:
|
||||
- persistTimeline
|
||||
required:
|
||||
- data
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_PersistTimelineResponse
|
||||
description: >-
|
||||
Indicates that the draft Timeline was successfully created. In the
|
||||
event the user already has a draft Timeline, the existing draft
|
||||
|
@ -20871,28 +20846,14 @@ paths:
|
|||
schema:
|
||||
type: object
|
||||
properties:
|
||||
file:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Security_Timeline_API_Readable'
|
||||
- type: object
|
||||
properties:
|
||||
hapi:
|
||||
type: object
|
||||
properties:
|
||||
filename:
|
||||
type: string
|
||||
headers:
|
||||
type: object
|
||||
isImmutable:
|
||||
enum:
|
||||
- 'true'
|
||||
- 'false'
|
||||
type: string
|
||||
required:
|
||||
- filename
|
||||
- headers
|
||||
required:
|
||||
- hapi
|
||||
file: {}
|
||||
isImmutable:
|
||||
enum:
|
||||
- 'true'
|
||||
- 'false'
|
||||
type: string
|
||||
required:
|
||||
- file
|
||||
description: The Timelines to import as a readable stream.
|
||||
required: true
|
||||
responses:
|
||||
|
@ -20900,13 +20861,8 @@ paths:
|
|||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_ImportTimelineResult
|
||||
required:
|
||||
- data
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_ImportTimelineResult
|
||||
description: Indicates the import of Timelines was successful.
|
||||
'400':
|
||||
content:
|
||||
|
@ -20965,7 +20921,9 @@ paths:
|
|||
properties:
|
||||
prepackagedTimelines:
|
||||
items:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_SavedTimeline'
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_TimelineSavedToReturnObject
|
||||
nullable: true
|
||||
type: array
|
||||
timelinesToInstall:
|
||||
items:
|
||||
|
@ -20988,13 +20946,8 @@ paths:
|
|||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_ImportTimelineResult
|
||||
required:
|
||||
- data
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_ImportTimelineResult
|
||||
description: Indicates the installation of prepackaged Timelines was successful.
|
||||
'500':
|
||||
content:
|
||||
|
@ -21032,19 +20985,16 @@ paths:
|
|||
content:
|
||||
application/json; Elastic-Api-Version=2023-10-31:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
oneOf:
|
||||
- type: object
|
||||
properties:
|
||||
getOneTimeline:
|
||||
data:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_TimelineResponse
|
||||
nullable: true
|
||||
#/components/schemas/Security_Timeline_API_ResolvedTimeline
|
||||
required:
|
||||
- getOneTimeline
|
||||
required:
|
||||
- data
|
||||
- data
|
||||
- additionalProperties: false
|
||||
type: object
|
||||
description: The (template) Timeline has been found
|
||||
'400':
|
||||
description: The request is missing parameters
|
||||
|
@ -21113,36 +21063,26 @@ paths:
|
|||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
customTemplateTimelineCount:
|
||||
type: number
|
||||
defaultTimelineCount:
|
||||
type: number
|
||||
elasticTemplateTimelineCount:
|
||||
type: number
|
||||
favoriteCount:
|
||||
type: number
|
||||
templateTimelineCount:
|
||||
type: number
|
||||
timelines:
|
||||
items:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_TimelineResponse
|
||||
type: array
|
||||
totalCount:
|
||||
type: number
|
||||
required:
|
||||
- timelines
|
||||
- totalCount
|
||||
- defaultTimelineCount
|
||||
- templateTimelineCount
|
||||
- favoriteCount
|
||||
- elasticTemplateTimelineCount
|
||||
- customTemplateTimelineCount
|
||||
customTemplateTimelineCount:
|
||||
type: number
|
||||
defaultTimelineCount:
|
||||
type: number
|
||||
elasticTemplateTimelineCount:
|
||||
type: number
|
||||
favoriteCount:
|
||||
type: number
|
||||
templateTimelineCount:
|
||||
type: number
|
||||
timeline:
|
||||
items:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_TimelineResponse
|
||||
type: array
|
||||
totalCount:
|
||||
type: number
|
||||
required:
|
||||
- data
|
||||
- timeline
|
||||
- totalCount
|
||||
description: Indicates that the (template) Timelines were found and returned.
|
||||
'400':
|
||||
content:
|
||||
|
@ -39344,30 +39284,39 @@ components:
|
|||
type: object
|
||||
properties:
|
||||
aggregatable:
|
||||
nullable: true
|
||||
type: boolean
|
||||
category:
|
||||
nullable: true
|
||||
type: string
|
||||
columnHeaderType:
|
||||
nullable: true
|
||||
type: string
|
||||
description:
|
||||
nullable: true
|
||||
type: string
|
||||
example:
|
||||
oneOf:
|
||||
- type: string
|
||||
- type: number
|
||||
nullable: true
|
||||
type: string
|
||||
id:
|
||||
nullable: true
|
||||
type: string
|
||||
indexes:
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
name:
|
||||
nullable: true
|
||||
type: string
|
||||
placeholder:
|
||||
nullable: true
|
||||
type: string
|
||||
searchable:
|
||||
nullable: true
|
||||
type: boolean
|
||||
type:
|
||||
nullable: true
|
||||
type: string
|
||||
Security_Timeline_API_DataProviderQueryMatch:
|
||||
type: object
|
||||
|
@ -39389,6 +39338,10 @@ components:
|
|||
type: string
|
||||
queryMatch:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_QueryMatchResult'
|
||||
nullable: true
|
||||
type:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_DataProviderType'
|
||||
nullable: true
|
||||
Security_Timeline_API_DataProviderResult:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -39476,41 +39429,59 @@ components:
|
|||
type: object
|
||||
properties:
|
||||
exists:
|
||||
type: boolean
|
||||
nullable: true
|
||||
type: string
|
||||
match_all:
|
||||
nullable: true
|
||||
type: string
|
||||
meta:
|
||||
nullable: true
|
||||
type: object
|
||||
properties:
|
||||
alias:
|
||||
nullable: true
|
||||
type: string
|
||||
controlledBy:
|
||||
nullable: true
|
||||
type: string
|
||||
disabled:
|
||||
nullable: true
|
||||
type: boolean
|
||||
field:
|
||||
nullable: true
|
||||
type: string
|
||||
formattedValue:
|
||||
nullable: true
|
||||
type: string
|
||||
index:
|
||||
nullable: true
|
||||
type: string
|
||||
key:
|
||||
nullable: true
|
||||
type: string
|
||||
negate:
|
||||
nullable: true
|
||||
type: boolean
|
||||
params:
|
||||
nullable: true
|
||||
type: string
|
||||
type:
|
||||
nullable: true
|
||||
type: string
|
||||
value:
|
||||
nullable: true
|
||||
type: string
|
||||
missing:
|
||||
nullable: true
|
||||
type: string
|
||||
query:
|
||||
nullable: true
|
||||
type: string
|
||||
range:
|
||||
nullable: true
|
||||
type: string
|
||||
script:
|
||||
nullable: true
|
||||
type: string
|
||||
Security_Timeline_API_GetNotesResult:
|
||||
type: object
|
||||
|
@ -39575,6 +39546,12 @@ components:
|
|||
version:
|
||||
nullable: true
|
||||
type: string
|
||||
required:
|
||||
- savedObjectId
|
||||
- version
|
||||
- pinnedEventIds
|
||||
- eventNotes
|
||||
- globalNotes
|
||||
Security_Timeline_API_Note:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Security_Timeline_API_BareNote'
|
||||
|
@ -39595,6 +39572,23 @@ components:
|
|||
#/components/schemas/Security_Timeline_API_PinnedEventBaseResponseBody
|
||||
- nullable: true
|
||||
type: object
|
||||
Security_Timeline_API_PersistTimelineResponse:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_TimelineResponse'
|
||||
required:
|
||||
- timeline
|
||||
required:
|
||||
- persistTimeline
|
||||
required:
|
||||
- data
|
||||
Security_Timeline_API_PinnedEvent:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Security_Timeline_API_BarePinnedEvent'
|
||||
|
@ -39632,34 +39626,29 @@ components:
|
|||
nullable: true
|
||||
type: string
|
||||
value:
|
||||
nullable: true
|
||||
type: string
|
||||
Security_Timeline_API_Readable:
|
||||
oneOf:
|
||||
- nullable: true
|
||||
type: string
|
||||
- items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
Security_Timeline_API_ResolvedTimeline:
|
||||
type: object
|
||||
properties:
|
||||
_data:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
_encoding:
|
||||
alias_purpose:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_SavedObjectResolveAliasPurpose
|
||||
alias_target_id:
|
||||
type: string
|
||||
_events:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
_eventsCount:
|
||||
type: number
|
||||
_maxListeners:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
_position:
|
||||
type: number
|
||||
_read:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
_readableState:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
readable:
|
||||
type: boolean
|
||||
outcome:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_SavedObjectResolveOutcome'
|
||||
timeline:
|
||||
$ref: >-
|
||||
#/components/schemas/Security_Timeline_API_TimelineSavedToReturnObject
|
||||
required:
|
||||
- timeline
|
||||
- outcome
|
||||
Security_Timeline_API_ResponseNote:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -39694,6 +39683,17 @@ components:
|
|||
- threat_match
|
||||
- zeek
|
||||
type: string
|
||||
Security_Timeline_API_SavedObjectResolveAliasPurpose:
|
||||
enum:
|
||||
- savedObjectConversion
|
||||
- savedObjectImport
|
||||
type: string
|
||||
Security_Timeline_API_SavedObjectResolveOutcome:
|
||||
enum:
|
||||
- exactMatch
|
||||
- aliasMatch
|
||||
- conflict
|
||||
type: string
|
||||
Security_Timeline_API_SavedTimeline:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -39722,12 +39722,16 @@ components:
|
|||
properties:
|
||||
end:
|
||||
oneOf:
|
||||
- type: string
|
||||
- type: number
|
||||
- nullable: true
|
||||
type: string
|
||||
- nullable: true
|
||||
type: number
|
||||
start:
|
||||
oneOf:
|
||||
- type: string
|
||||
- type: number
|
||||
- nullable: true
|
||||
type: string
|
||||
- nullable: true
|
||||
type: number
|
||||
description:
|
||||
nullable: true
|
||||
type: string
|
||||
|
@ -39817,6 +39821,18 @@ components:
|
|||
updatedBy:
|
||||
nullable: true
|
||||
type: string
|
||||
Security_Timeline_API_SavedTimelineWithSavedObjectId:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Security_Timeline_API_SavedTimeline'
|
||||
- type: object
|
||||
properties:
|
||||
savedObjectId:
|
||||
type: string
|
||||
version:
|
||||
type: string
|
||||
required:
|
||||
- savedObjectId
|
||||
- version
|
||||
Security_Timeline_API_SerializedFilterQueryResult:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -39866,27 +39882,64 @@ components:
|
|||
Security_Timeline_API_TimelineResponse:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Security_Timeline_API_SavedTimeline'
|
||||
- $ref: >-
|
||||
#/components/schemas/Security_Timeline_API_SavedTimelineWithSavedObjectId
|
||||
- type: object
|
||||
properties:
|
||||
eventIdToNoteIds:
|
||||
items:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_Note'
|
||||
nullable: true
|
||||
type: array
|
||||
noteIds:
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
notes:
|
||||
items:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_Note'
|
||||
nullable: true
|
||||
type: array
|
||||
pinnedEventIds:
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
pinnedEventsSaveObject:
|
||||
items:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_PinnedEvent'
|
||||
nullable: true
|
||||
type: array
|
||||
Security_Timeline_API_TimelineSavedToReturnObject:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Security_Timeline_API_SavedTimeline'
|
||||
- type: object
|
||||
properties:
|
||||
eventIdToNoteIds:
|
||||
items:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_Note'
|
||||
nullable: true
|
||||
type: array
|
||||
noteIds:
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
notes:
|
||||
items:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_Note'
|
||||
nullable: true
|
||||
type: array
|
||||
pinnedEventIds:
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
pinnedEventsSaveObject:
|
||||
items:
|
||||
$ref: '#/components/schemas/Security_Timeline_API_PinnedEvent'
|
||||
nullable: true
|
||||
type: array
|
||||
savedObjectId:
|
||||
type: string
|
||||
|
|
|
@ -296,6 +296,10 @@ import type {
|
|||
CleanDraftTimelinesRequestBodyInput,
|
||||
CleanDraftTimelinesResponse,
|
||||
} from './timeline/clean_draft_timelines/clean_draft_timelines_route.gen';
|
||||
import type {
|
||||
CopyTimelineRequestBodyInput,
|
||||
CopyTimelineResponse,
|
||||
} from './timeline/copy_timeline/copy_timeline_route.gen';
|
||||
import type {
|
||||
CreateTimelinesRequestBodyInput,
|
||||
CreateTimelinesResponse,
|
||||
|
@ -556,6 +560,23 @@ If asset criticality records already exist for the specified entities, those rec
|
|||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
/**
|
||||
* Copies and returns a timeline or timeline template.
|
||||
|
||||
*/
|
||||
async copyTimeline(props: CopyTimelineProps) {
|
||||
this.log.info(`${new Date().toISOString()} Calling API CopyTimeline`);
|
||||
return this.kbnClient
|
||||
.request<CopyTimelineResponse>({
|
||||
path: '/api/timeline/_copy',
|
||||
headers: {
|
||||
[ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31',
|
||||
},
|
||||
method: 'GET',
|
||||
body: props.body,
|
||||
})
|
||||
.catch(catchAxiosErrorFormatAndThrow);
|
||||
}
|
||||
async createAlertsIndex() {
|
||||
this.log.info(`${new Date().toISOString()} Calling API CreateAlertsIndex`);
|
||||
return this.kbnClient
|
||||
|
@ -1993,6 +2014,9 @@ export interface BulkUpsertAssetCriticalityRecordsProps {
|
|||
export interface CleanDraftTimelinesProps {
|
||||
body: CleanDraftTimelinesRequestBodyInput;
|
||||
}
|
||||
export interface CopyTimelineProps {
|
||||
body: CopyTimelineRequestBodyInput;
|
||||
}
|
||||
export interface CreateAlertsMigrationProps {
|
||||
body: CreateAlertsMigrationRequestBodyInput;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
import { TimelineType, TimelineResponse } from '../model/components.gen';
|
||||
import { TimelineType, PersistTimelineResponse } from '../model/components.gen';
|
||||
|
||||
export type CleanDraftTimelinesRequestBody = z.infer<typeof CleanDraftTimelinesRequestBody>;
|
||||
export const CleanDraftTimelinesRequestBody = z.object({
|
||||
|
@ -25,10 +25,4 @@ export const CleanDraftTimelinesRequestBody = z.object({
|
|||
export type CleanDraftTimelinesRequestBodyInput = z.input<typeof CleanDraftTimelinesRequestBody>;
|
||||
|
||||
export type CleanDraftTimelinesResponse = z.infer<typeof CleanDraftTimelinesResponse>;
|
||||
export const CleanDraftTimelinesResponse = z.object({
|
||||
data: z.object({
|
||||
persistTimeline: z.object({
|
||||
timeline: TimelineResponse,
|
||||
}),
|
||||
}),
|
||||
});
|
||||
export const CleanDraftTimelinesResponse = PersistTimelineResponse;
|
||||
|
|
|
@ -2,13 +2,6 @@ openapi: 3.0.0
|
|||
info:
|
||||
title: Elastic Security - Timeline - Draft Timeline API
|
||||
version: '2023-10-31'
|
||||
servers:
|
||||
- url: 'http://{kibana_host}:{port}'
|
||||
variables:
|
||||
kibana_host:
|
||||
default: localhost
|
||||
port:
|
||||
default: '5601'
|
||||
paths:
|
||||
/api/timeline/_draft:
|
||||
post:
|
||||
|
@ -39,19 +32,7 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [data]
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
required: [persistTimeline]
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
required: [timeline]
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/TimelineResponse'
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/PersistTimelineResponse'
|
||||
'403':
|
||||
description: Indicates that the user does not have the required permissions to create a draft Timeline.
|
||||
content:
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTICE: Do not edit this file manually.
|
||||
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
|
||||
*
|
||||
* info:
|
||||
* title: Elastic Security - Timeline - Copy Timeline API
|
||||
* version: 2023-10-31
|
||||
*/
|
||||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
import { SavedTimeline, PersistTimelineResponse } from '../model/components.gen';
|
||||
|
||||
export type CopyTimelineRequestBody = z.infer<typeof CopyTimelineRequestBody>;
|
||||
export const CopyTimelineRequestBody = z.object({
|
||||
timeline: SavedTimeline,
|
||||
timelineIdToCopy: z.string(),
|
||||
});
|
||||
export type CopyTimelineRequestBodyInput = z.input<typeof CopyTimelineRequestBody>;
|
||||
|
||||
export type CopyTimelineResponse = z.infer<typeof CopyTimelineResponse>;
|
||||
export const CopyTimelineResponse = PersistTimelineResponse;
|
|
@ -0,0 +1,34 @@
|
|||
openapi: 3.0.0
|
||||
info:
|
||||
title: Elastic Security - Timeline - Copy Timeline API
|
||||
version: '2023-10-31'
|
||||
paths:
|
||||
/api/timeline/_copy:
|
||||
get:
|
||||
x-labels: [serverless, ess]
|
||||
x-codegen-enabled: true
|
||||
operationId: CopyTimeline
|
||||
summary: Copies timeline or timeline template
|
||||
description: |
|
||||
Copies and returns a timeline or timeline template.
|
||||
tags:
|
||||
- access:securitySolution
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [timeline, timelineIdToCopy]
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/SavedTimeline'
|
||||
timelineIdToCopy:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: Indicates that the timeline has been successfully copied.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/PersistTimelineResponse'
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import * as rt from 'io-ts';
|
||||
|
||||
import { SavedTimelineRuntimeType } from '../model/api';
|
||||
|
||||
export const copyTimelineSchema = rt.type({
|
||||
timeline: SavedTimelineRuntimeType,
|
||||
timelineIdToCopy: rt.string,
|
||||
});
|
|
@ -17,29 +17,23 @@
|
|||
import { z } from '@kbn/zod';
|
||||
|
||||
import {
|
||||
SavedTimeline,
|
||||
TimelineStatus,
|
||||
TimelineType,
|
||||
SavedTimeline,
|
||||
TimelineResponse,
|
||||
PersistTimelineResponse,
|
||||
} from '../model/components.gen';
|
||||
|
||||
export type CreateTimelinesRequestBody = z.infer<typeof CreateTimelinesRequestBody>;
|
||||
export const CreateTimelinesRequestBody = z.object({
|
||||
timeline: SavedTimeline,
|
||||
status: TimelineStatus.nullable().optional(),
|
||||
timelineId: z.string().nullable().optional(),
|
||||
templateTimelineId: z.string().nullable().optional(),
|
||||
templateTimelineVersion: z.number().nullable().optional(),
|
||||
timelineType: TimelineType.nullable().optional(),
|
||||
version: z.string().nullable().optional(),
|
||||
timeline: SavedTimeline,
|
||||
});
|
||||
export type CreateTimelinesRequestBodyInput = z.input<typeof CreateTimelinesRequestBody>;
|
||||
|
||||
export type CreateTimelinesResponse = z.infer<typeof CreateTimelinesResponse>;
|
||||
export const CreateTimelinesResponse = z.object({
|
||||
data: z.object({
|
||||
persistTimeline: z.object({
|
||||
timeline: TimelineResponse.optional(),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
export const CreateTimelinesResponse = PersistTimelineResponse;
|
||||
|
|
|
@ -5,13 +5,6 @@ info:
|
|||
externalDocs:
|
||||
url: https://www.elastic.co/guide/en/security/current/timeline-api-create.html
|
||||
description: Documentation
|
||||
servers:
|
||||
- url: 'http://{kibana_host}:{port}'
|
||||
variables:
|
||||
kibana_host:
|
||||
default: localhost
|
||||
port:
|
||||
default: '5601'
|
||||
paths:
|
||||
/api/timeline:
|
||||
post:
|
||||
|
@ -29,9 +22,10 @@ paths:
|
|||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- timeline
|
||||
required: [timeline]
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/SavedTimeline'
|
||||
status:
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/TimelineStatus'
|
||||
nullable: true
|
||||
|
@ -50,26 +44,13 @@ paths:
|
|||
version:
|
||||
type: string
|
||||
nullable: true
|
||||
timeline:
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/SavedTimeline'
|
||||
responses:
|
||||
'200':
|
||||
description: Indicates the Timeline was successfully created.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [data]
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
required: [persistTimeline]
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/TimelineResponse'
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/PersistTimelineResponse'
|
||||
'405':
|
||||
description: Indicates that there was an error in the Timeline creation.
|
||||
content:
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import * as rt from 'io-ts';
|
||||
|
||||
import type { ResponseTimeline } from '../model/api';
|
||||
import {
|
||||
SavedTimelineRuntimeType,
|
||||
TimelineStatusLiteralRt,
|
||||
TimelineTypeLiteralRt,
|
||||
} from '../model/api';
|
||||
import { unionWithNullType } from '../../../utility_types';
|
||||
|
||||
export const createTimelineSchema = rt.intersection([
|
||||
rt.type({
|
||||
timeline: SavedTimelineRuntimeType,
|
||||
}),
|
||||
rt.partial({
|
||||
status: unionWithNullType(TimelineStatusLiteralRt),
|
||||
timelineId: unionWithNullType(rt.string),
|
||||
templateTimelineId: unionWithNullType(rt.string),
|
||||
templateTimelineVersion: unionWithNullType(rt.number),
|
||||
timelineType: unionWithNullType(TimelineTypeLiteralRt),
|
||||
version: unionWithNullType(rt.string),
|
||||
}),
|
||||
]);
|
||||
|
||||
export interface CreateTimelinesResponse {
|
||||
data: {
|
||||
persistTimeline: ResponseTimeline;
|
||||
};
|
||||
}
|
|
@ -2,13 +2,6 @@ openapi: 3.0.0
|
|||
info:
|
||||
title: Elastic Security - Timeline - Notes API
|
||||
version: '2023-10-31'
|
||||
servers:
|
||||
- url: 'http://{kibana_host}:{port}'
|
||||
variables:
|
||||
kibana_host:
|
||||
default: localhost
|
||||
port:
|
||||
default: '5601'
|
||||
paths:
|
||||
/api/note:
|
||||
delete:
|
||||
|
|
|
@ -5,13 +5,6 @@ info:
|
|||
externalDocs:
|
||||
url: https://www.elastic.co/guide/en/security/current/timeline-api-delete.html
|
||||
description: Documentation
|
||||
servers:
|
||||
- url: 'http://{kibana_host}:{port}'
|
||||
variables:
|
||||
kibana_host:
|
||||
default: localhost
|
||||
port:
|
||||
default: '5601'
|
||||
paths:
|
||||
/api/timeline:
|
||||
delete:
|
||||
|
|
|
@ -5,13 +5,6 @@ info:
|
|||
externalDocs:
|
||||
url: https://www.elastic.co/guide/en/security/current/timeline-api-import.html
|
||||
description: Documentation
|
||||
servers:
|
||||
- url: 'http://{kibana_host}:{port}'
|
||||
variables:
|
||||
kibana_host:
|
||||
default: localhost
|
||||
port:
|
||||
default: '5601'
|
||||
paths:
|
||||
/api/timeline/_export:
|
||||
post:
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
import { TimelineType, TimelineResponse } from '../model/components.gen';
|
||||
import { TimelineType, PersistTimelineResponse } from '../model/components.gen';
|
||||
|
||||
export type GetDraftTimelinesRequestQuery = z.infer<typeof GetDraftTimelinesRequestQuery>;
|
||||
export const GetDraftTimelinesRequestQuery = z.object({
|
||||
|
@ -25,10 +25,4 @@ export const GetDraftTimelinesRequestQuery = z.object({
|
|||
export type GetDraftTimelinesRequestQueryInput = z.input<typeof GetDraftTimelinesRequestQuery>;
|
||||
|
||||
export type GetDraftTimelinesResponse = z.infer<typeof GetDraftTimelinesResponse>;
|
||||
export const GetDraftTimelinesResponse = z.object({
|
||||
data: z.object({
|
||||
persistTimeline: z.object({
|
||||
timeline: TimelineResponse,
|
||||
}),
|
||||
}),
|
||||
});
|
||||
export const GetDraftTimelinesResponse = PersistTimelineResponse;
|
||||
|
|
|
@ -2,13 +2,6 @@ openapi: 3.0.0
|
|||
info:
|
||||
title: Elastic Security - Timeline - Get Draft Timelines API
|
||||
version: '2023-10-31'
|
||||
servers:
|
||||
- url: 'http://{kibana_host}:{port}'
|
||||
variables:
|
||||
kibana_host:
|
||||
default: localhost
|
||||
port:
|
||||
default: '5601'
|
||||
paths:
|
||||
/api/timeline/_draft:
|
||||
get:
|
||||
|
@ -31,19 +24,7 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [data]
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
required: [persistTimeline]
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
required: [timeline]
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/TimelineResponse'
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/PersistTimelineResponse'
|
||||
'403':
|
||||
description: If a draft Timeline was not found and we attempted to create one, it indicates that the user does not have the required permissions to create a draft Timeline.
|
||||
content:
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import * as rt from 'io-ts';
|
||||
|
||||
import { TimelineTypeLiteralRt } from '../model/api';
|
||||
|
||||
export const getDraftTimelineSchema = rt.type({
|
||||
timelineType: TimelineTypeLiteralRt,
|
||||
});
|
|
@ -2,13 +2,6 @@ openapi: 3.0.0
|
|||
info:
|
||||
title: Elastic Security - Timeline - Notes API
|
||||
version: '2023-10-31'
|
||||
servers:
|
||||
- url: 'http://{kibana_host}:{port}'
|
||||
variables:
|
||||
kibana_host:
|
||||
default: localhost
|
||||
port:
|
||||
default: '5601'
|
||||
paths:
|
||||
/api/note:
|
||||
get:
|
||||
|
|
|
@ -32,8 +32,11 @@ export const GetTimelineRequestQuery = z.object({
|
|||
export type GetTimelineRequestQueryInput = z.input<typeof GetTimelineRequestQuery>;
|
||||
|
||||
export type GetTimelineResponse = z.infer<typeof GetTimelineResponse>;
|
||||
export const GetTimelineResponse = z.object({
|
||||
data: z.object({
|
||||
getOneTimeline: TimelineResponse.nullable(),
|
||||
export const GetTimelineResponse = z.union([
|
||||
z.object({
|
||||
data: z.object({
|
||||
getOneTimeline: TimelineResponse,
|
||||
}),
|
||||
}),
|
||||
});
|
||||
z.object({}).strict(),
|
||||
]);
|
||||
|
|
|
@ -5,13 +5,6 @@ info:
|
|||
externalDocs:
|
||||
url: https://www.elastic.co/guide/en/security/current/_get_timeline_or_timeline_template_by_savedobjectid.html
|
||||
description: Documentation
|
||||
servers:
|
||||
- url: 'http://{kibana_host}:{port}'
|
||||
variables:
|
||||
kibana_host:
|
||||
default: localhost
|
||||
port:
|
||||
default: '5601'
|
||||
paths:
|
||||
/api/timeline:
|
||||
get:
|
||||
|
@ -39,13 +32,15 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [data]
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
required: [getOneTimeline]
|
||||
oneOf:
|
||||
- type: object
|
||||
required: [data]
|
||||
properties:
|
||||
getOneTimeline:
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/TimelineResponse'
|
||||
nullable: true
|
||||
data:
|
||||
type: object
|
||||
required: [getOneTimeline]
|
||||
properties:
|
||||
getOneTimeline:
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/TimelineResponse'
|
||||
- type: object
|
||||
additionalProperties: false
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import * as rt from 'io-ts';
|
||||
|
||||
export const getTimelineQuerySchema = rt.partial({
|
||||
template_timeline_id: rt.string,
|
||||
id: rt.string,
|
||||
});
|
||||
|
||||
export type GetTimelineQuery = rt.TypeOf<typeof getTimelineQuerySchema>;
|
|
@ -41,13 +41,11 @@ export type GetTimelinesRequestQueryInput = z.input<typeof GetTimelinesRequestQu
|
|||
|
||||
export type GetTimelinesResponse = z.infer<typeof GetTimelinesResponse>;
|
||||
export const GetTimelinesResponse = z.object({
|
||||
data: z.object({
|
||||
timelines: z.array(TimelineResponse),
|
||||
totalCount: z.number(),
|
||||
defaultTimelineCount: z.number(),
|
||||
templateTimelineCount: z.number(),
|
||||
favoriteCount: z.number(),
|
||||
elasticTemplateTimelineCount: z.number(),
|
||||
customTemplateTimelineCount: z.number(),
|
||||
}),
|
||||
timeline: z.array(TimelineResponse),
|
||||
totalCount: z.number(),
|
||||
defaultTimelineCount: z.number().optional(),
|
||||
templateTimelineCount: z.number().optional(),
|
||||
favoriteCount: z.number().optional(),
|
||||
elasticTemplateTimelineCount: z.number().optional(),
|
||||
customTemplateTimelineCount: z.number().optional(),
|
||||
});
|
||||
|
|
|
@ -5,13 +5,6 @@ info:
|
|||
externalDocs:
|
||||
url: https://www.elastic.co/guide/en/security/current/timeline-api-get.html
|
||||
description: Documentation
|
||||
servers:
|
||||
- url: 'http://{kibana_host}:{port}'
|
||||
variables:
|
||||
kibana_host:
|
||||
default: localhost
|
||||
port:
|
||||
default: '5601'
|
||||
paths:
|
||||
/api/timelines:
|
||||
get:
|
||||
|
@ -75,37 +68,27 @@ paths:
|
|||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [data]
|
||||
required: [
|
||||
timeline,
|
||||
totalCount,
|
||||
]
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
required:
|
||||
[
|
||||
timelines,
|
||||
totalCount,
|
||||
defaultTimelineCount,
|
||||
templateTimelineCount,
|
||||
favoriteCount,
|
||||
elasticTemplateTimelineCount,
|
||||
customTemplateTimelineCount,
|
||||
]
|
||||
properties:
|
||||
timelines:
|
||||
type: array
|
||||
items:
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/TimelineResponse'
|
||||
totalCount:
|
||||
type: number
|
||||
defaultTimelineCount:
|
||||
type: number
|
||||
templateTimelineCount:
|
||||
type: number
|
||||
favoriteCount:
|
||||
type: number
|
||||
elasticTemplateTimelineCount:
|
||||
type: number
|
||||
customTemplateTimelineCount:
|
||||
type: number
|
||||
timeline:
|
||||
type: array
|
||||
items:
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/TimelineResponse'
|
||||
totalCount:
|
||||
type: number
|
||||
defaultTimelineCount:
|
||||
type: number
|
||||
templateTimelineCount:
|
||||
type: number
|
||||
favoriteCount:
|
||||
type: number
|
||||
elasticTemplateTimelineCount:
|
||||
type: number
|
||||
customTemplateTimelineCount:
|
||||
type: number
|
||||
'400':
|
||||
description: Bad request. The user supplied invalid data.
|
||||
content:
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import * as rt from 'io-ts';
|
||||
import {
|
||||
direction,
|
||||
sortFieldTimeline,
|
||||
TimelineStatusLiteralRt,
|
||||
TimelineTypeLiteralRt,
|
||||
} from '../model/api';
|
||||
import { unionWithNullType } from '../../../utility_types';
|
||||
|
||||
const BoolFromString = rt.union([rt.literal('true'), rt.literal('false')]);
|
||||
|
||||
export const getTimelinesQuerySchema = rt.partial({
|
||||
only_user_favorite: unionWithNullType(BoolFromString),
|
||||
page_index: unionWithNullType(rt.string),
|
||||
page_size: unionWithNullType(rt.string),
|
||||
search: unionWithNullType(rt.string),
|
||||
sort_field: sortFieldTimeline,
|
||||
sort_order: direction,
|
||||
status: unionWithNullType(TimelineStatusLiteralRt),
|
||||
timeline_type: unionWithNullType(TimelineTypeLiteralRt),
|
||||
});
|
|
@ -16,23 +16,14 @@
|
|||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
import { Readable, ImportTimelineResult } from '../model/components.gen';
|
||||
import { ImportTimelineResult } from '../model/components.gen';
|
||||
|
||||
export type ImportTimelinesRequestBody = z.infer<typeof ImportTimelinesRequestBody>;
|
||||
export const ImportTimelinesRequestBody = z.object({
|
||||
file: Readable.merge(
|
||||
z.object({
|
||||
hapi: z.object({
|
||||
filename: z.string(),
|
||||
headers: z.object({}),
|
||||
isImmutable: z.enum(['true', 'false']).optional(),
|
||||
}),
|
||||
})
|
||||
),
|
||||
isImmutable: z.enum(['true', 'false']).optional(),
|
||||
file: z.unknown(),
|
||||
});
|
||||
export type ImportTimelinesRequestBodyInput = z.input<typeof ImportTimelinesRequestBody>;
|
||||
|
||||
export type ImportTimelinesResponse = z.infer<typeof ImportTimelinesResponse>;
|
||||
export const ImportTimelinesResponse = z.object({
|
||||
data: ImportTimelineResult,
|
||||
});
|
||||
export const ImportTimelinesResponse = ImportTimelineResult;
|
||||
|
|
|
@ -5,13 +5,6 @@ info:
|
|||
externalDocs:
|
||||
url: https://www.elastic.co/guide/en/security/current/timeline-api-import.html
|
||||
description: Documentation
|
||||
servers:
|
||||
- url: 'http://{kibana_host}:{port}'
|
||||
variables:
|
||||
kibana_host:
|
||||
default: localhost
|
||||
port:
|
||||
default: '5601'
|
||||
paths:
|
||||
/api/timeline/_import:
|
||||
post:
|
||||
|
@ -29,37 +22,21 @@ paths:
|
|||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [file]
|
||||
properties:
|
||||
file:
|
||||
allOf:
|
||||
- $ref: '../model/components.schema.yaml#/components/schemas/Readable'
|
||||
- type: object
|
||||
required: [hapi]
|
||||
properties:
|
||||
hapi:
|
||||
type: object
|
||||
required: [filename, headers]
|
||||
properties:
|
||||
filename:
|
||||
type: string
|
||||
headers:
|
||||
type: object
|
||||
isImmutable:
|
||||
type: string
|
||||
enum:
|
||||
- 'true'
|
||||
- 'false'
|
||||
isImmutable:
|
||||
type: string
|
||||
enum:
|
||||
- 'true'
|
||||
- 'false'
|
||||
file: {}
|
||||
responses:
|
||||
'200':
|
||||
description: Indicates the import of Timelines was successful.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [data]
|
||||
properties:
|
||||
data:
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/ImportTimelineResult'
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/ImportTimelineResult'
|
||||
|
||||
'400':
|
||||
description: Indicates the import of Timelines was unsuccessful because of an invalid file extension.
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import * as rt from 'io-ts';
|
||||
|
||||
import { BareNoteSchema, SavedTimelineRuntimeType } from '../model/api';
|
||||
import { unionWithNullType } from '../../../utility_types';
|
||||
|
||||
const pinnedEventIds = unionWithNullType(rt.array(rt.string));
|
||||
|
||||
export const eventNotes = unionWithNullType(rt.array(BareNoteSchema));
|
||||
export const globalNotes = unionWithNullType(rt.array(BareNoteSchema));
|
||||
|
||||
export const ImportTimelinesSchemaRt = rt.intersection([
|
||||
SavedTimelineRuntimeType,
|
||||
rt.type({
|
||||
savedObjectId: unionWithNullType(rt.string),
|
||||
version: unionWithNullType(rt.string),
|
||||
}),
|
||||
rt.type({
|
||||
globalNotes,
|
||||
eventNotes,
|
||||
pinnedEventIds,
|
||||
}),
|
||||
]);
|
||||
|
||||
export type ImportTimelinesSchema = rt.TypeOf<typeof ImportTimelinesSchemaRt>;
|
||||
|
||||
const ReadableRt = rt.partial({
|
||||
_maxListeners: rt.unknown,
|
||||
_readableState: rt.unknown,
|
||||
_read: rt.unknown,
|
||||
readable: rt.boolean,
|
||||
_events: rt.unknown,
|
||||
_eventsCount: rt.number,
|
||||
_data: rt.unknown,
|
||||
_position: rt.number,
|
||||
_encoding: rt.string,
|
||||
});
|
||||
|
||||
const booleanInString = rt.union([rt.literal('true'), rt.literal('false')]);
|
||||
|
||||
export const ImportTimelinesPayloadSchemaRt = rt.intersection([
|
||||
rt.type({
|
||||
file: rt.intersection([
|
||||
ReadableRt,
|
||||
rt.type({
|
||||
hapi: rt.type({
|
||||
filename: rt.string,
|
||||
headers: rt.unknown,
|
||||
}),
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
rt.partial({ isImmutable: booleanInString }),
|
||||
]);
|
|
@ -7,13 +7,3 @@
|
|||
|
||||
export * from './model/api';
|
||||
export * from './routes';
|
||||
|
||||
export * from './get_draft_timelines/get_draft_timelines_route';
|
||||
export * from './create_timelines/create_timelines_route';
|
||||
export * from './get_timeline/get_timeline_route';
|
||||
export * from './get_timelines/get_timelines_route';
|
||||
export * from './import_timelines/import_timelines_route';
|
||||
export * from './patch_timelines/patch_timelines_schema';
|
||||
export * from './pinned_events/pinned_events_route';
|
||||
export * from './install_prepackaged_timelines/install_prepackaged_timelines';
|
||||
export * from './copy_timeline/copy_timeline_route';
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import * as rt from 'io-ts';
|
||||
|
||||
import { unionWithNullType } from '../../../utility_types';
|
||||
import { ImportTimelinesSchemaRt, TimelineSavedToReturnObjectRuntimeType } from '..';
|
||||
|
||||
export const checkTimelineStatusRt = rt.type({
|
||||
timelinesToInstall: rt.array(unionWithNullType(ImportTimelinesSchemaRt)),
|
||||
timelinesToUpdate: rt.array(unionWithNullType(ImportTimelinesSchemaRt)),
|
||||
prepackagedTimelines: rt.array(unionWithNullType(TimelineSavedToReturnObjectRuntimeType)),
|
||||
});
|
||||
|
||||
export type CheckTimelineStatusRt = rt.TypeOf<typeof checkTimelineStatusRt>;
|
|
@ -16,7 +16,11 @@
|
|||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
import { ImportTimelines, SavedTimeline, ImportTimelineResult } from '../model/components.gen';
|
||||
import {
|
||||
ImportTimelines,
|
||||
TimelineSavedToReturnObject,
|
||||
ImportTimelineResult,
|
||||
} from '../model/components.gen';
|
||||
|
||||
export type InstallPrepackedTimelinesRequestBody = z.infer<
|
||||
typeof InstallPrepackedTimelinesRequestBody
|
||||
|
@ -24,13 +28,11 @@ export type InstallPrepackedTimelinesRequestBody = z.infer<
|
|||
export const InstallPrepackedTimelinesRequestBody = z.object({
|
||||
timelinesToInstall: z.array(ImportTimelines.nullable()),
|
||||
timelinesToUpdate: z.array(ImportTimelines.nullable()),
|
||||
prepackagedTimelines: z.array(SavedTimeline),
|
||||
prepackagedTimelines: z.array(TimelineSavedToReturnObject.nullable()),
|
||||
});
|
||||
export type InstallPrepackedTimelinesRequestBodyInput = z.input<
|
||||
typeof InstallPrepackedTimelinesRequestBody
|
||||
>;
|
||||
|
||||
export type InstallPrepackedTimelinesResponse = z.infer<typeof InstallPrepackedTimelinesResponse>;
|
||||
export const InstallPrepackedTimelinesResponse = z.object({
|
||||
data: ImportTimelineResult,
|
||||
});
|
||||
export const InstallPrepackedTimelinesResponse = ImportTimelineResult;
|
||||
|
|
|
@ -2,13 +2,6 @@ openapi: 3.0.0
|
|||
info:
|
||||
title: Elastic Security - Timeline - Install Prepackaged Timelines API
|
||||
version: '2023-10-31'
|
||||
servers:
|
||||
- url: 'http://{kibana_host}:{port}'
|
||||
variables:
|
||||
kibana_host:
|
||||
default: localhost
|
||||
port:
|
||||
default: '5601'
|
||||
paths:
|
||||
/api/timeline/_prepackaged:
|
||||
post:
|
||||
|
@ -41,18 +34,15 @@ paths:
|
|||
prepackagedTimelines:
|
||||
type: array
|
||||
items:
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/SavedTimeline'
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/TimelineSavedToReturnObject'
|
||||
nullable: true
|
||||
responses:
|
||||
'200':
|
||||
description: Indicates the installation of prepackaged Timelines was successful.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [data]
|
||||
properties:
|
||||
data:
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/ImportTimelineResult'
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/ImportTimelineResult'
|
||||
'500':
|
||||
description: Indicates the installation of prepackaged Timelines was unsuccessful.
|
||||
content:
|
||||
|
|
|
@ -5,30 +5,35 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import * as runtimeTypes from 'io-ts';
|
||||
import { PositiveInteger } from '@kbn/securitysolution-io-ts-types';
|
||||
|
||||
import { stringEnum, unionWithNullType } from '../../../utility_types';
|
||||
|
||||
import type { Maybe } from '../../../search_strategy';
|
||||
import { Direction } from '../../../search_strategy';
|
||||
import { PinnedEventRuntimeType } from '../pinned_events/pinned_events_route';
|
||||
import { ErrorSchema } from './error_schema';
|
||||
import type { DataProviderType } from './components.gen';
|
||||
import {
|
||||
BareNote,
|
||||
BarePinnedEvent,
|
||||
ColumnHeaderResult,
|
||||
DataProviderTypeEnum,
|
||||
DataProviderResult,
|
||||
FavoriteTimelineResponse,
|
||||
type FavoriteTimelineResult,
|
||||
FilterTimelineResult,
|
||||
ImportTimelineResult,
|
||||
ImportTimelines,
|
||||
type Note,
|
||||
PinnedEvent,
|
||||
PersistTimelineResponse,
|
||||
QueryMatchResult,
|
||||
ResolvedTimeline,
|
||||
RowRendererId,
|
||||
RowRendererIdEnum,
|
||||
SavedTimeline,
|
||||
SavedTimelineWithSavedObjectId,
|
||||
Sort,
|
||||
SortDirection,
|
||||
SortFieldTimeline,
|
||||
SortFieldTimelineEnum,
|
||||
TemplateTimelineType,
|
||||
TemplateTimelineTypeEnum,
|
||||
TimelineErrorResponse,
|
||||
TimelineResponse,
|
||||
TimelineSavedToReturnObject,
|
||||
TimelineStatus,
|
||||
TimelineStatusEnum,
|
||||
TimelineType,
|
||||
|
@ -38,412 +43,54 @@ import {
|
|||
export {
|
||||
BareNote,
|
||||
BarePinnedEvent,
|
||||
ColumnHeaderResult,
|
||||
DataProviderResult,
|
||||
DataProviderType,
|
||||
DataProviderTypeEnum,
|
||||
FavoriteTimelineResponse,
|
||||
FilterTimelineResult,
|
||||
ImportTimelineResult,
|
||||
ImportTimelines,
|
||||
Note,
|
||||
PinnedEvent,
|
||||
PersistTimelineResponse,
|
||||
QueryMatchResult,
|
||||
ResolvedTimeline,
|
||||
RowRendererId,
|
||||
RowRendererIdEnum,
|
||||
SavedTimeline,
|
||||
SavedTimelineWithSavedObjectId,
|
||||
Sort,
|
||||
SortDirection,
|
||||
SortFieldTimeline,
|
||||
SortFieldTimelineEnum,
|
||||
TemplateTimelineType,
|
||||
TimelineErrorResponse,
|
||||
TimelineResponse,
|
||||
TemplateTimelineTypeEnum,
|
||||
TimelineSavedToReturnObject,
|
||||
TimelineStatus,
|
||||
TimelineStatusEnum,
|
||||
TimelineType,
|
||||
TimelineTypeEnum,
|
||||
};
|
||||
|
||||
export type BarePinnedEventWithoutExternalRefs = Omit<BarePinnedEvent, 'timelineId'>;
|
||||
|
||||
/**
|
||||
* Outcome is a property of the saved object resolve api
|
||||
* will tell us info about the rule after 8.0 migrations
|
||||
*/
|
||||
export type SavedObjectResolveOutcome = runtimeTypes.TypeOf<typeof SavedObjectResolveOutcome>;
|
||||
export const SavedObjectResolveOutcome = runtimeTypes.union([
|
||||
runtimeTypes.literal('exactMatch'),
|
||||
runtimeTypes.literal('aliasMatch'),
|
||||
runtimeTypes.literal('conflict'),
|
||||
]);
|
||||
|
||||
export type SavedObjectResolveAliasTargetId = runtimeTypes.TypeOf<
|
||||
typeof SavedObjectResolveAliasTargetId
|
||||
>;
|
||||
export const SavedObjectResolveAliasTargetId = runtimeTypes.string;
|
||||
|
||||
export type SavedObjectResolveAliasPurpose = runtimeTypes.TypeOf<
|
||||
typeof SavedObjectResolveAliasPurpose
|
||||
>;
|
||||
export const SavedObjectResolveAliasPurpose = runtimeTypes.union([
|
||||
runtimeTypes.literal('savedObjectConversion'),
|
||||
runtimeTypes.literal('savedObjectImport'),
|
||||
]);
|
||||
|
||||
export const BareNoteSchema = runtimeTypes.intersection([
|
||||
runtimeTypes.type({
|
||||
timelineId: runtimeTypes.string,
|
||||
}),
|
||||
runtimeTypes.partial({
|
||||
eventId: unionWithNullType(runtimeTypes.string),
|
||||
note: unionWithNullType(runtimeTypes.string),
|
||||
created: unionWithNullType(runtimeTypes.number),
|
||||
createdBy: unionWithNullType(runtimeTypes.string),
|
||||
updated: unionWithNullType(runtimeTypes.number),
|
||||
updatedBy: unionWithNullType(runtimeTypes.string),
|
||||
}),
|
||||
]);
|
||||
|
||||
/**
|
||||
* This type represents a note type stored in a saved object that does not include any fields that reference
|
||||
* other saved objects.
|
||||
*/
|
||||
export type BareNoteWithoutExternalRefs = Omit<BareNote, 'timelineId'>;
|
||||
|
||||
export const NoteRuntimeType = runtimeTypes.intersection([
|
||||
BareNoteSchema,
|
||||
runtimeTypes.type({
|
||||
noteId: runtimeTypes.string,
|
||||
version: runtimeTypes.string,
|
||||
}),
|
||||
]);
|
||||
|
||||
/*
|
||||
* ColumnHeader Types
|
||||
*/
|
||||
const SavedColumnHeaderRuntimeType = runtimeTypes.partial({
|
||||
aggregatable: unionWithNullType(runtimeTypes.boolean),
|
||||
category: unionWithNullType(runtimeTypes.string),
|
||||
columnHeaderType: unionWithNullType(runtimeTypes.string),
|
||||
description: unionWithNullType(runtimeTypes.string),
|
||||
example: unionWithNullType(runtimeTypes.string),
|
||||
indexes: unionWithNullType(runtimeTypes.array(runtimeTypes.string)),
|
||||
id: unionWithNullType(runtimeTypes.string),
|
||||
name: unionWithNullType(runtimeTypes.string),
|
||||
placeholder: unionWithNullType(runtimeTypes.string),
|
||||
searchable: unionWithNullType(runtimeTypes.boolean),
|
||||
type: unionWithNullType(runtimeTypes.string),
|
||||
});
|
||||
|
||||
/*
|
||||
* DataProvider Types
|
||||
*/
|
||||
const SavedDataProviderQueryMatchBasicRuntimeType = runtimeTypes.partial({
|
||||
field: unionWithNullType(runtimeTypes.string),
|
||||
displayField: unionWithNullType(runtimeTypes.string),
|
||||
value: runtimeTypes.union([
|
||||
runtimeTypes.null,
|
||||
runtimeTypes.string,
|
||||
runtimeTypes.array(runtimeTypes.string),
|
||||
]),
|
||||
displayValue: unionWithNullType(runtimeTypes.string),
|
||||
operator: unionWithNullType(runtimeTypes.string),
|
||||
});
|
||||
|
||||
const SavedDataProviderQueryMatchRuntimeType = runtimeTypes.partial({
|
||||
id: unionWithNullType(runtimeTypes.string),
|
||||
name: unionWithNullType(runtimeTypes.string),
|
||||
enabled: unionWithNullType(runtimeTypes.boolean),
|
||||
excluded: unionWithNullType(runtimeTypes.boolean),
|
||||
kqlQuery: unionWithNullType(runtimeTypes.string),
|
||||
queryMatch: unionWithNullType(SavedDataProviderQueryMatchBasicRuntimeType),
|
||||
});
|
||||
|
||||
export const DataProviderTypeLiteralRt = runtimeTypes.union([
|
||||
runtimeTypes.literal(DataProviderTypeEnum.default),
|
||||
runtimeTypes.literal(DataProviderTypeEnum.template),
|
||||
]);
|
||||
|
||||
const SavedDataProviderRuntimeType = runtimeTypes.partial({
|
||||
id: unionWithNullType(runtimeTypes.string),
|
||||
name: unionWithNullType(runtimeTypes.string),
|
||||
enabled: unionWithNullType(runtimeTypes.boolean),
|
||||
excluded: unionWithNullType(runtimeTypes.boolean),
|
||||
kqlQuery: unionWithNullType(runtimeTypes.string),
|
||||
queryMatch: unionWithNullType(SavedDataProviderQueryMatchBasicRuntimeType),
|
||||
and: unionWithNullType(runtimeTypes.array(SavedDataProviderQueryMatchRuntimeType)),
|
||||
type: unionWithNullType(DataProviderTypeLiteralRt),
|
||||
});
|
||||
|
||||
/*
|
||||
* Filters Types
|
||||
*/
|
||||
const SavedFilterMetaRuntimeType = runtimeTypes.partial({
|
||||
alias: unionWithNullType(runtimeTypes.string),
|
||||
controlledBy: unionWithNullType(runtimeTypes.string),
|
||||
disabled: unionWithNullType(runtimeTypes.boolean),
|
||||
field: unionWithNullType(runtimeTypes.string),
|
||||
formattedValue: unionWithNullType(runtimeTypes.string),
|
||||
index: unionWithNullType(runtimeTypes.string),
|
||||
key: unionWithNullType(runtimeTypes.string),
|
||||
negate: unionWithNullType(runtimeTypes.boolean),
|
||||
params: unionWithNullType(runtimeTypes.string),
|
||||
type: unionWithNullType(runtimeTypes.string),
|
||||
value: unionWithNullType(runtimeTypes.string),
|
||||
});
|
||||
|
||||
const SavedFilterRuntimeType = runtimeTypes.partial({
|
||||
exists: unionWithNullType(runtimeTypes.string),
|
||||
meta: unionWithNullType(SavedFilterMetaRuntimeType),
|
||||
match_all: unionWithNullType(runtimeTypes.string),
|
||||
missing: unionWithNullType(runtimeTypes.string),
|
||||
query: unionWithNullType(runtimeTypes.string),
|
||||
range: unionWithNullType(runtimeTypes.string),
|
||||
script: unionWithNullType(runtimeTypes.string),
|
||||
});
|
||||
|
||||
/*
|
||||
* eqlOptionsQuery -> filterQuery Types
|
||||
*/
|
||||
const EqlOptionsRuntimeType = runtimeTypes.partial({
|
||||
eventCategoryField: unionWithNullType(runtimeTypes.string),
|
||||
query: unionWithNullType(runtimeTypes.string),
|
||||
tiebreakerField: unionWithNullType(runtimeTypes.string),
|
||||
timestampField: unionWithNullType(runtimeTypes.string),
|
||||
size: unionWithNullType(runtimeTypes.union([runtimeTypes.string, runtimeTypes.number])),
|
||||
});
|
||||
|
||||
/*
|
||||
* kqlQuery -> filterQuery Types
|
||||
*/
|
||||
const SavedKueryFilterQueryRuntimeType = runtimeTypes.partial({
|
||||
kind: unionWithNullType(runtimeTypes.string),
|
||||
expression: unionWithNullType(runtimeTypes.string),
|
||||
});
|
||||
|
||||
const SavedSerializedFilterQueryQueryRuntimeType = runtimeTypes.partial({
|
||||
kuery: unionWithNullType(SavedKueryFilterQueryRuntimeType),
|
||||
serializedQuery: unionWithNullType(runtimeTypes.string),
|
||||
});
|
||||
|
||||
const SavedFilterQueryQueryRuntimeType = runtimeTypes.partial({
|
||||
filterQuery: unionWithNullType(SavedSerializedFilterQueryQueryRuntimeType),
|
||||
});
|
||||
|
||||
/*
|
||||
* DatePicker Range Types
|
||||
*/
|
||||
const SavedDateRangePickerRuntimeType = runtimeTypes.partial({
|
||||
/* Before the change of all timestamp to ISO string the values of start and from
|
||||
* attributes where a number. Specifically UNIX timestamps.
|
||||
* To support old timeline's saved object we need to add the number io-ts type
|
||||
*/
|
||||
start: unionWithNullType(runtimeTypes.union([runtimeTypes.string, runtimeTypes.number])),
|
||||
end: unionWithNullType(runtimeTypes.union([runtimeTypes.string, runtimeTypes.number])),
|
||||
});
|
||||
|
||||
/*
|
||||
* Favorite Types
|
||||
*/
|
||||
const SavedFavoriteRuntimeType = runtimeTypes.partial({
|
||||
keySearch: unionWithNullType(runtimeTypes.string),
|
||||
favoriteDate: unionWithNullType(runtimeTypes.number),
|
||||
fullName: unionWithNullType(runtimeTypes.string),
|
||||
userName: unionWithNullType(runtimeTypes.string),
|
||||
});
|
||||
|
||||
/*
|
||||
* Sort Types
|
||||
*/
|
||||
|
||||
const SavedSortObject = runtimeTypes.partial({
|
||||
columnId: unionWithNullType(runtimeTypes.string),
|
||||
columnType: unionWithNullType(runtimeTypes.string),
|
||||
sortDirection: unionWithNullType(runtimeTypes.string),
|
||||
});
|
||||
const SavedSortRuntimeType = runtimeTypes.union([
|
||||
runtimeTypes.array(SavedSortObject),
|
||||
SavedSortObject,
|
||||
]);
|
||||
|
||||
export type Sort = runtimeTypes.TypeOf<typeof SavedSortRuntimeType>;
|
||||
|
||||
/*
|
||||
* Timeline Statuses
|
||||
*/
|
||||
|
||||
export const TimelineStatusLiteralRt = runtimeTypes.union([
|
||||
runtimeTypes.literal(TimelineStatusEnum.active),
|
||||
runtimeTypes.literal(TimelineStatusEnum.draft),
|
||||
runtimeTypes.literal(TimelineStatusEnum.immutable),
|
||||
]);
|
||||
|
||||
export const RowRendererCount = Object.keys(RowRendererIdEnum).length;
|
||||
export const RowRendererValues = Object.values(RowRendererId.Values);
|
||||
|
||||
const RowRendererIdRuntimeType = stringEnum(RowRendererIdEnum, 'RowRendererId');
|
||||
|
||||
/**
|
||||
* Timeline types
|
||||
*/
|
||||
|
||||
export const TimelineTypeLiteralRt = runtimeTypes.union([
|
||||
runtimeTypes.literal(TimelineTypeEnum.template),
|
||||
runtimeTypes.literal(TimelineTypeEnum.default),
|
||||
]);
|
||||
|
||||
/**
|
||||
* This is the response type
|
||||
*/
|
||||
export const SavedTimelineRuntimeType = runtimeTypes.partial({
|
||||
columns: unionWithNullType(runtimeTypes.array(SavedColumnHeaderRuntimeType)),
|
||||
dataProviders: unionWithNullType(runtimeTypes.array(SavedDataProviderRuntimeType)),
|
||||
dataViewId: unionWithNullType(runtimeTypes.string),
|
||||
description: unionWithNullType(runtimeTypes.string),
|
||||
eqlOptions: unionWithNullType(EqlOptionsRuntimeType),
|
||||
eventType: unionWithNullType(runtimeTypes.string),
|
||||
excludedRowRendererIds: unionWithNullType(runtimeTypes.array(RowRendererIdRuntimeType)),
|
||||
favorite: unionWithNullType(runtimeTypes.array(SavedFavoriteRuntimeType)),
|
||||
filters: unionWithNullType(runtimeTypes.array(SavedFilterRuntimeType)),
|
||||
indexNames: unionWithNullType(runtimeTypes.array(runtimeTypes.string)),
|
||||
kqlMode: unionWithNullType(runtimeTypes.string),
|
||||
kqlQuery: unionWithNullType(SavedFilterQueryQueryRuntimeType),
|
||||
title: unionWithNullType(runtimeTypes.string),
|
||||
templateTimelineId: unionWithNullType(runtimeTypes.string),
|
||||
templateTimelineVersion: unionWithNullType(runtimeTypes.number),
|
||||
timelineType: unionWithNullType(TimelineTypeLiteralRt),
|
||||
dateRange: unionWithNullType(SavedDateRangePickerRuntimeType),
|
||||
savedQueryId: unionWithNullType(runtimeTypes.string),
|
||||
sort: unionWithNullType(SavedSortRuntimeType),
|
||||
status: unionWithNullType(TimelineStatusLiteralRt),
|
||||
created: unionWithNullType(runtimeTypes.number),
|
||||
createdBy: unionWithNullType(runtimeTypes.string),
|
||||
updated: unionWithNullType(runtimeTypes.number),
|
||||
updatedBy: unionWithNullType(runtimeTypes.string),
|
||||
savedSearchId: unionWithNullType(runtimeTypes.string),
|
||||
});
|
||||
|
||||
export type SavedTimeline = runtimeTypes.TypeOf<typeof SavedTimelineRuntimeType>;
|
||||
|
||||
export type SavedTimelineWithSavedObjectId = SavedTimeline & {
|
||||
savedObjectId?: string | null;
|
||||
};
|
||||
|
||||
/**
|
||||
* This type represents a timeline type stored in a saved object that does not include any fields that reference
|
||||
* other saved objects.
|
||||
*/
|
||||
export type TimelineWithoutExternalRefs = Omit<SavedTimeline, 'dataViewId' | 'savedQueryId'>;
|
||||
|
||||
export const TimelineSavedToReturnObjectRuntimeType = runtimeTypes.intersection([
|
||||
SavedTimelineRuntimeType,
|
||||
runtimeTypes.type({
|
||||
savedObjectId: runtimeTypes.string,
|
||||
version: runtimeTypes.string,
|
||||
}),
|
||||
runtimeTypes.partial({
|
||||
eventIdToNoteIds: runtimeTypes.array(NoteRuntimeType),
|
||||
noteIds: runtimeTypes.array(runtimeTypes.string),
|
||||
notes: runtimeTypes.array(NoteRuntimeType),
|
||||
pinnedEventIds: runtimeTypes.array(runtimeTypes.string),
|
||||
pinnedEventsSaveObject: runtimeTypes.array(PinnedEventRuntimeType),
|
||||
}),
|
||||
]);
|
||||
|
||||
export type TimelineSavedObject = runtimeTypes.TypeOf<
|
||||
typeof TimelineSavedToReturnObjectRuntimeType
|
||||
>;
|
||||
|
||||
export const SingleTimelineResponseType = runtimeTypes.type({
|
||||
data: runtimeTypes.type({
|
||||
getOneTimeline: TimelineSavedToReturnObjectRuntimeType,
|
||||
}),
|
||||
});
|
||||
|
||||
export type SingleTimelineResponse = runtimeTypes.TypeOf<typeof SingleTimelineResponseType>;
|
||||
|
||||
/** Resolved Timeline Response */
|
||||
export const ResolvedTimelineSavedObjectToReturnObjectRuntimeType = runtimeTypes.intersection([
|
||||
runtimeTypes.type({
|
||||
timeline: TimelineSavedToReturnObjectRuntimeType,
|
||||
outcome: SavedObjectResolveOutcome,
|
||||
}),
|
||||
runtimeTypes.partial({
|
||||
alias_target_id: SavedObjectResolveAliasTargetId,
|
||||
alias_purpose: SavedObjectResolveAliasPurpose,
|
||||
}),
|
||||
]);
|
||||
|
||||
export type ResolvedTimelineWithOutcomeSavedObject = runtimeTypes.TypeOf<
|
||||
typeof ResolvedTimelineSavedObjectToReturnObjectRuntimeType
|
||||
>;
|
||||
|
||||
export const ResolvedSingleTimelineResponseType = runtimeTypes.type({
|
||||
data: ResolvedTimelineSavedObjectToReturnObjectRuntimeType,
|
||||
});
|
||||
|
||||
export type SingleTimelineResolveResponse = runtimeTypes.TypeOf<
|
||||
typeof ResolvedSingleTimelineResponseType
|
||||
>;
|
||||
|
||||
const responseTimelines = runtimeTypes.type({
|
||||
timeline: runtimeTypes.array(TimelineSavedToReturnObjectRuntimeType),
|
||||
totalCount: runtimeTypes.number,
|
||||
});
|
||||
|
||||
export type ResponseTimelines = runtimeTypes.TypeOf<typeof responseTimelines>;
|
||||
|
||||
export const allTimelinesResponse = runtimeTypes.intersection([
|
||||
responseTimelines,
|
||||
runtimeTypes.type({
|
||||
defaultTimelineCount: runtimeTypes.number,
|
||||
templateTimelineCount: runtimeTypes.number,
|
||||
elasticTemplateTimelineCount: runtimeTypes.number,
|
||||
customTemplateTimelineCount: runtimeTypes.number,
|
||||
favoriteCount: runtimeTypes.number,
|
||||
}),
|
||||
]);
|
||||
|
||||
export type AllTimelinesResponse = runtimeTypes.TypeOf<typeof allTimelinesResponse>;
|
||||
export type BarePinnedEventWithoutExternalRefs = Omit<BarePinnedEvent, 'timelineId'>;
|
||||
|
||||
/**
|
||||
* All Timeline Saved object type with metadata
|
||||
* This type represents a note type stored in a saved object that does not include any fields that reference
|
||||
* other saved objects.
|
||||
*/
|
||||
export const TimelineResponseType = runtimeTypes.type({
|
||||
data: runtimeTypes.type({
|
||||
persistTimeline: runtimeTypes.intersection([
|
||||
runtimeTypes.partial({
|
||||
code: unionWithNullType(runtimeTypes.number),
|
||||
message: unionWithNullType(runtimeTypes.string),
|
||||
}),
|
||||
runtimeTypes.type({
|
||||
timeline: TimelineSavedToReturnObjectRuntimeType,
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
});
|
||||
export type BareNoteWithoutExternalRefs = Omit<BareNote, 'timelineId'>;
|
||||
|
||||
export const TimelineErrorResponseType = runtimeTypes.union([
|
||||
runtimeTypes.type({
|
||||
status_code: runtimeTypes.number,
|
||||
message: runtimeTypes.string,
|
||||
}),
|
||||
runtimeTypes.type({
|
||||
statusCode: runtimeTypes.number,
|
||||
message: runtimeTypes.string,
|
||||
}),
|
||||
]);
|
||||
|
||||
export type TimelineErrorResponse = runtimeTypes.TypeOf<typeof TimelineErrorResponseType>;
|
||||
export type TimelineResponse = runtimeTypes.TypeOf<typeof TimelineResponseType>;
|
||||
|
||||
export const sortFieldTimeline = runtimeTypes.union([
|
||||
runtimeTypes.literal(SortFieldTimelineEnum.title),
|
||||
runtimeTypes.literal(SortFieldTimelineEnum.description),
|
||||
runtimeTypes.literal(SortFieldTimelineEnum.updated),
|
||||
runtimeTypes.literal(SortFieldTimelineEnum.created),
|
||||
]);
|
||||
|
||||
export const direction = runtimeTypes.union([
|
||||
runtimeTypes.literal(Direction.asc),
|
||||
runtimeTypes.literal(Direction.desc),
|
||||
]);
|
||||
|
||||
export const sortTimeline = runtimeTypes.type({
|
||||
sortField: sortFieldTimeline,
|
||||
sortOrder: direction,
|
||||
});
|
||||
export const RowRendererCount = Object.keys(RowRendererIdEnum).length;
|
||||
export const RowRendererValues = Object.values(RowRendererId.Values);
|
||||
|
||||
/**
|
||||
* Import/export timelines
|
||||
|
@ -457,187 +104,17 @@ export interface ExportedNotes {
|
|||
globalNotes: ExportedGlobalNotes;
|
||||
}
|
||||
|
||||
export type ExportedTimelines = SavedTimeline &
|
||||
ExportedNotes & {
|
||||
pinnedEventIds: string[];
|
||||
};
|
||||
|
||||
export interface ExportTimelineNotFoundError {
|
||||
statusCode: number;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export const importTimelineResultSchema = runtimeTypes.exact(
|
||||
runtimeTypes.type({
|
||||
success: runtimeTypes.boolean,
|
||||
success_count: PositiveInteger,
|
||||
timelines_installed: PositiveInteger,
|
||||
timelines_updated: PositiveInteger,
|
||||
errors: runtimeTypes.array(ErrorSchema),
|
||||
})
|
||||
);
|
||||
|
||||
export type ImportTimelineResultSchema = runtimeTypes.TypeOf<typeof importTimelineResultSchema>;
|
||||
|
||||
export const pageInfoTimeline = runtimeTypes.type({
|
||||
pageIndex: runtimeTypes.number,
|
||||
pageSize: runtimeTypes.number,
|
||||
});
|
||||
|
||||
export interface PageInfoTimeline {
|
||||
pageIndex: number;
|
||||
pageSize: number;
|
||||
}
|
||||
|
||||
export const getTimelinesArgs = runtimeTypes.partial({
|
||||
onlyUserFavorite: unionWithNullType(runtimeTypes.boolean),
|
||||
pageInfo: unionWithNullType(pageInfoTimeline),
|
||||
search: unionWithNullType(runtimeTypes.string),
|
||||
sort: unionWithNullType(sortTimeline),
|
||||
status: unionWithNullType(TimelineStatusLiteralRt),
|
||||
timelineType: unionWithNullType(TimelineTypeLiteralRt),
|
||||
});
|
||||
|
||||
export type GetTimelinesArgs = runtimeTypes.TypeOf<typeof getTimelinesArgs>;
|
||||
|
||||
export interface ColumnHeaderResult {
|
||||
aggregatable?: Maybe<boolean>;
|
||||
category?: Maybe<string>;
|
||||
columnHeaderType?: Maybe<string>;
|
||||
description?: Maybe<string>;
|
||||
example?: Maybe<string | number>;
|
||||
indexes?: Maybe<string[]>;
|
||||
id?: Maybe<string>;
|
||||
name?: Maybe<string>;
|
||||
placeholder?: Maybe<string>;
|
||||
searchable?: Maybe<boolean>;
|
||||
type?: Maybe<string>;
|
||||
}
|
||||
|
||||
export interface DataProviderResult {
|
||||
id?: Maybe<string>;
|
||||
name?: Maybe<string>;
|
||||
enabled?: Maybe<boolean>;
|
||||
excluded?: Maybe<boolean>;
|
||||
kqlQuery?: Maybe<string>;
|
||||
queryMatch?: Maybe<QueryMatchResult>;
|
||||
type?: Maybe<DataProviderType>;
|
||||
and?: Maybe<DataProviderResult[]>;
|
||||
}
|
||||
|
||||
export interface QueryMatchResult {
|
||||
field?: Maybe<string>;
|
||||
displayField?: Maybe<string>;
|
||||
value?: Maybe<string | string[]>;
|
||||
displayValue?: Maybe<string>;
|
||||
operator?: Maybe<string>;
|
||||
}
|
||||
|
||||
export interface DateRangePickerResult {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
start?: Maybe<any>;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
end?: Maybe<any>;
|
||||
}
|
||||
|
||||
export interface EqlOptionsResult {
|
||||
eventCategoryField?: Maybe<string>;
|
||||
tiebreakerField?: Maybe<string>;
|
||||
timestampField?: Maybe<string>;
|
||||
query?: Maybe<string>;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
size?: Maybe<any>;
|
||||
}
|
||||
|
||||
export interface FilterTimelineResult {
|
||||
exists?: Maybe<string>;
|
||||
meta?: Maybe<FilterMetaTimelineResult>;
|
||||
match_all?: Maybe<string>;
|
||||
missing?: Maybe<string>;
|
||||
query?: Maybe<string>;
|
||||
range?: Maybe<string>;
|
||||
script?: Maybe<string>;
|
||||
}
|
||||
|
||||
export interface FilterMetaTimelineResult {
|
||||
alias?: Maybe<string>;
|
||||
controlledBy?: Maybe<string>;
|
||||
disabled?: Maybe<boolean>;
|
||||
field?: Maybe<string>;
|
||||
formattedValue?: Maybe<string>;
|
||||
index?: Maybe<string>;
|
||||
key?: Maybe<string>;
|
||||
negate?: Maybe<boolean>;
|
||||
params?: Maybe<string>;
|
||||
type?: Maybe<string>;
|
||||
value?: Maybe<string>;
|
||||
}
|
||||
|
||||
export interface SerializedFilterQueryResult {
|
||||
filterQuery?: Maybe<SerializedKueryQueryResult>;
|
||||
}
|
||||
|
||||
export interface KueryFilterQueryResult {
|
||||
kind?: Maybe<string>;
|
||||
expression?: Maybe<string>;
|
||||
}
|
||||
|
||||
export interface SerializedKueryQueryResult {
|
||||
kuery?: Maybe<KueryFilterQueryResult>;
|
||||
serializedQuery?: Maybe<string>;
|
||||
}
|
||||
|
||||
export interface TimelineResult {
|
||||
columns?: Maybe<ColumnHeaderResult[]>;
|
||||
created?: Maybe<number>;
|
||||
createdBy?: Maybe<string>;
|
||||
dataProviders?: Maybe<DataProviderResult[]>;
|
||||
dataViewId?: Maybe<string>;
|
||||
dateRange?: Maybe<DateRangePickerResult>;
|
||||
description?: Maybe<string>;
|
||||
eqlOptions?: Maybe<EqlOptionsResult>;
|
||||
eventIdToNoteIds?: Maybe<Note[]>;
|
||||
eventType?: Maybe<string>;
|
||||
excludedRowRendererIds?: Maybe<RowRendererId[]>;
|
||||
favorite?: Maybe<FavoriteTimelineResult[]>;
|
||||
filters?: Maybe<FilterTimelineResult[]>;
|
||||
kqlMode?: Maybe<string>;
|
||||
kqlQuery?: Maybe<SerializedFilterQueryResult>;
|
||||
indexNames?: Maybe<string[]>;
|
||||
notes?: Maybe<Note[]>;
|
||||
noteIds?: Maybe<string[]>;
|
||||
pinnedEventIds?: Maybe<string[]>;
|
||||
pinnedEventsSaveObject?: Maybe<PinnedEvent[]>;
|
||||
savedQueryId?: Maybe<string>;
|
||||
savedObjectId: string;
|
||||
sort?: Maybe<Sort>;
|
||||
status?: Maybe<TimelineStatus>;
|
||||
title?: Maybe<string>;
|
||||
templateTimelineId?: Maybe<string>;
|
||||
templateTimelineVersion?: Maybe<number>;
|
||||
timelineType?: Maybe<TimelineType>;
|
||||
updated?: Maybe<number>;
|
||||
updatedBy?: Maybe<string>;
|
||||
version: string;
|
||||
savedSearchId?: Maybe<string>;
|
||||
}
|
||||
|
||||
export interface ResponseTimeline {
|
||||
code?: Maybe<number>;
|
||||
message?: Maybe<string>;
|
||||
timeline: TimelineResult;
|
||||
}
|
||||
|
||||
export interface SortTimeline {
|
||||
sortField: SortFieldTimeline;
|
||||
sortOrder: Direction;
|
||||
}
|
||||
|
||||
export interface GetAllTimelineVariables {
|
||||
pageInfo: PageInfoTimeline;
|
||||
search?: Maybe<string>;
|
||||
sort?: Maybe<SortTimeline>;
|
||||
onlyUserFavorite?: Maybe<boolean>;
|
||||
timelineType?: Maybe<TimelineType>;
|
||||
status?: Maybe<TimelineStatus>;
|
||||
sortOrder: SortDirection;
|
||||
}
|
||||
|
|
|
@ -42,24 +42,24 @@ export const TemplateTimelineTypeEnum = TemplateTimelineType.enum;
|
|||
|
||||
export type ColumnHeaderResult = z.infer<typeof ColumnHeaderResult>;
|
||||
export const ColumnHeaderResult = z.object({
|
||||
aggregatable: z.boolean().optional(),
|
||||
category: z.string().optional(),
|
||||
columnHeaderType: z.string().optional(),
|
||||
description: z.string().optional(),
|
||||
example: z.union([z.string(), z.number()]).optional(),
|
||||
indexes: z.array(z.string()).optional(),
|
||||
id: z.string().optional(),
|
||||
name: z.string().optional(),
|
||||
placeholder: z.string().optional(),
|
||||
searchable: z.boolean().optional(),
|
||||
type: z.string().optional(),
|
||||
aggregatable: z.boolean().nullable().optional(),
|
||||
category: z.string().nullable().optional(),
|
||||
columnHeaderType: z.string().nullable().optional(),
|
||||
description: z.string().nullable().optional(),
|
||||
example: z.string().nullable().optional(),
|
||||
indexes: z.array(z.string()).nullable().optional(),
|
||||
id: z.string().nullable().optional(),
|
||||
name: z.string().nullable().optional(),
|
||||
placeholder: z.string().nullable().optional(),
|
||||
searchable: z.boolean().nullable().optional(),
|
||||
type: z.string().nullable().optional(),
|
||||
});
|
||||
|
||||
export type QueryMatchResult = z.infer<typeof QueryMatchResult>;
|
||||
export const QueryMatchResult = z.object({
|
||||
field: z.string().nullable().optional(),
|
||||
displayField: z.string().nullable().optional(),
|
||||
value: z.string().nullable().optional(),
|
||||
value: z.union([z.string().nullable(), z.array(z.string()).nullable()]).optional(),
|
||||
displayValue: z.string().nullable().optional(),
|
||||
operator: z.string().nullable().optional(),
|
||||
});
|
||||
|
@ -71,7 +71,8 @@ export const DataProviderQueryMatch = z.object({
|
|||
id: z.string().nullable().optional(),
|
||||
kqlQuery: z.string().nullable().optional(),
|
||||
name: z.string().nullable().optional(),
|
||||
queryMatch: QueryMatchResult.optional(),
|
||||
queryMatch: QueryMatchResult.nullable().optional(),
|
||||
type: DataProviderType.nullable().optional(),
|
||||
});
|
||||
|
||||
export type DataProviderResult = z.infer<typeof DataProviderResult>;
|
||||
|
@ -119,27 +120,28 @@ export const FavoriteTimelineResult = z.object({
|
|||
|
||||
export type FilterTimelineResult = z.infer<typeof FilterTimelineResult>;
|
||||
export const FilterTimelineResult = z.object({
|
||||
exists: z.boolean().optional(),
|
||||
exists: z.string().nullable().optional(),
|
||||
meta: z
|
||||
.object({
|
||||
alias: z.string().optional(),
|
||||
controlledBy: z.string().optional(),
|
||||
disabled: z.boolean().optional(),
|
||||
field: z.string().optional(),
|
||||
formattedValue: z.string().optional(),
|
||||
index: z.string().optional(),
|
||||
key: z.string().optional(),
|
||||
negate: z.boolean().optional(),
|
||||
params: z.string().optional(),
|
||||
type: z.string().optional(),
|
||||
value: z.string().optional(),
|
||||
alias: z.string().nullable().optional(),
|
||||
controlledBy: z.string().nullable().optional(),
|
||||
disabled: z.boolean().nullable().optional(),
|
||||
field: z.string().nullable().optional(),
|
||||
formattedValue: z.string().nullable().optional(),
|
||||
index: z.string().nullable().optional(),
|
||||
key: z.string().nullable().optional(),
|
||||
negate: z.boolean().nullable().optional(),
|
||||
params: z.string().nullable().optional(),
|
||||
type: z.string().nullable().optional(),
|
||||
value: z.string().nullable().optional(),
|
||||
})
|
||||
.nullable()
|
||||
.optional(),
|
||||
match_all: z.string().optional(),
|
||||
missing: z.string().optional(),
|
||||
query: z.string().optional(),
|
||||
range: z.string().optional(),
|
||||
script: z.string().optional(),
|
||||
match_all: z.string().nullable().optional(),
|
||||
missing: z.string().nullable().optional(),
|
||||
query: z.string().nullable().optional(),
|
||||
range: z.string().nullable().optional(),
|
||||
script: z.string().nullable().optional(),
|
||||
});
|
||||
|
||||
export type SerializedFilterQueryResult = z.infer<typeof SerializedFilterQueryResult>;
|
||||
|
@ -178,8 +180,8 @@ export const SavedTimeline = z.object({
|
|||
dataViewId: z.string().nullable().optional(),
|
||||
dateRange: z
|
||||
.object({
|
||||
end: z.union([z.string(), z.number()]).optional(),
|
||||
start: z.union([z.string(), z.number()]).optional(),
|
||||
end: z.union([z.string().nullable(), z.number().nullable()]).optional(),
|
||||
start: z.union([z.string().nullable(), z.number().nullable()]).optional(),
|
||||
})
|
||||
.nullable()
|
||||
.optional(),
|
||||
|
@ -213,6 +215,14 @@ export const SavedTimeline = z.object({
|
|||
updatedBy: z.string().nullable().optional(),
|
||||
});
|
||||
|
||||
export type SavedTimelineWithSavedObjectId = z.infer<typeof SavedTimelineWithSavedObjectId>;
|
||||
export const SavedTimelineWithSavedObjectId = SavedTimeline.merge(
|
||||
z.object({
|
||||
savedObjectId: z.string(),
|
||||
version: z.string(),
|
||||
})
|
||||
);
|
||||
|
||||
export type BareNote = z.infer<typeof BareNote>;
|
||||
export const BareNote = z.object({
|
||||
eventId: z.string().nullable().optional(),
|
||||
|
@ -251,18 +261,50 @@ export const PinnedEvent = BarePinnedEvent.merge(
|
|||
);
|
||||
|
||||
export type TimelineResponse = z.infer<typeof TimelineResponse>;
|
||||
export const TimelineResponse = SavedTimeline.merge(
|
||||
export const TimelineResponse = SavedTimeline.merge(SavedTimelineWithSavedObjectId).merge(
|
||||
z.object({
|
||||
eventIdToNoteIds: z.array(Note).optional(),
|
||||
notes: z.array(Note).optional(),
|
||||
noteIds: z.array(z.string()).optional(),
|
||||
pinnedEventIds: z.array(z.string()).optional(),
|
||||
pinnedEventsSaveObject: z.array(PinnedEvent).optional(),
|
||||
savedObjectId: z.string(),
|
||||
version: z.string(),
|
||||
eventIdToNoteIds: z.array(Note).nullable().optional(),
|
||||
notes: z.array(Note).nullable().optional(),
|
||||
noteIds: z.array(z.string()).nullable().optional(),
|
||||
pinnedEventIds: z.array(z.string()).nullable().optional(),
|
||||
pinnedEventsSaveObject: z.array(PinnedEvent).nullable().optional(),
|
||||
})
|
||||
);
|
||||
|
||||
export type TimelineSavedToReturnObject = z.infer<typeof TimelineSavedToReturnObject>;
|
||||
export const TimelineSavedToReturnObject = SavedTimeline.merge(
|
||||
z.object({
|
||||
savedObjectId: z.string(),
|
||||
version: z.string(),
|
||||
eventIdToNoteIds: z.array(Note).nullable().optional(),
|
||||
notes: z.array(Note).nullable().optional(),
|
||||
noteIds: z.array(z.string()).nullable().optional(),
|
||||
pinnedEventIds: z.array(z.string()).nullable().optional(),
|
||||
pinnedEventsSaveObject: z.array(PinnedEvent).nullable().optional(),
|
||||
})
|
||||
);
|
||||
|
||||
export type SavedObjectResolveOutcome = z.infer<typeof SavedObjectResolveOutcome>;
|
||||
export const SavedObjectResolveOutcome = z.enum(['exactMatch', 'aliasMatch', 'conflict']);
|
||||
export type SavedObjectResolveOutcomeEnum = typeof SavedObjectResolveOutcome.enum;
|
||||
export const SavedObjectResolveOutcomeEnum = SavedObjectResolveOutcome.enum;
|
||||
|
||||
export type SavedObjectResolveAliasPurpose = z.infer<typeof SavedObjectResolveAliasPurpose>;
|
||||
export const SavedObjectResolveAliasPurpose = z.enum([
|
||||
'savedObjectConversion',
|
||||
'savedObjectImport',
|
||||
]);
|
||||
export type SavedObjectResolveAliasPurposeEnum = typeof SavedObjectResolveAliasPurpose.enum;
|
||||
export const SavedObjectResolveAliasPurposeEnum = SavedObjectResolveAliasPurpose.enum;
|
||||
|
||||
export type ResolvedTimeline = z.infer<typeof ResolvedTimeline>;
|
||||
export const ResolvedTimeline = z.object({
|
||||
timeline: TimelineSavedToReturnObject,
|
||||
outcome: SavedObjectResolveOutcome,
|
||||
alias_target_id: z.string().optional(),
|
||||
alias_purpose: SavedObjectResolveAliasPurpose.optional(),
|
||||
});
|
||||
|
||||
export type FavoriteTimelineResponse = z.infer<typeof FavoriteTimelineResponse>;
|
||||
export const FavoriteTimelineResponse = z.object({
|
||||
savedObjectId: z.string(),
|
||||
|
@ -275,6 +317,15 @@ export const FavoriteTimelineResponse = z.object({
|
|||
favorite: z.array(FavoriteTimelineResult).optional(),
|
||||
});
|
||||
|
||||
export type PersistTimelineResponse = z.infer<typeof PersistTimelineResponse>;
|
||||
export const PersistTimelineResponse = z.object({
|
||||
data: z.object({
|
||||
persistTimeline: z.object({
|
||||
timeline: TimelineResponse,
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
export type BareNoteWithoutExternalRefs = z.infer<typeof BareNoteWithoutExternalRefs>;
|
||||
export const BareNoteWithoutExternalRefs = z.object({
|
||||
eventId: z.string().nullable().optional(),
|
||||
|
@ -306,6 +357,11 @@ export const SortFieldTimeline = z.enum(['title', 'description', 'updated', 'cre
|
|||
export type SortFieldTimelineEnum = typeof SortFieldTimeline.enum;
|
||||
export const SortFieldTimelineEnum = SortFieldTimeline.enum;
|
||||
|
||||
export type SortDirection = z.infer<typeof SortDirection>;
|
||||
export const SortDirection = z.enum(['asc', 'desc']);
|
||||
export type SortDirectionEnum = typeof SortDirection.enum;
|
||||
export const SortDirectionEnum = SortDirection.enum;
|
||||
|
||||
/**
|
||||
* The status of the timeline. Valid values are `active`, `draft`, and `immutable`.
|
||||
*/
|
||||
|
@ -317,11 +373,11 @@ export const TimelineStatusEnum = TimelineStatus.enum;
|
|||
export type ImportTimelines = z.infer<typeof ImportTimelines>;
|
||||
export const ImportTimelines = SavedTimeline.merge(
|
||||
z.object({
|
||||
savedObjectId: z.string().nullable().optional(),
|
||||
version: z.string().nullable().optional(),
|
||||
globalNotes: z.array(BareNote).nullable().optional(),
|
||||
eventNotes: z.array(BareNote).nullable().optional(),
|
||||
pinnedEventIds: z.array(z.string()).nullable().optional(),
|
||||
savedObjectId: z.string().nullable(),
|
||||
version: z.string().nullable(),
|
||||
pinnedEventIds: z.array(z.string()).nullable(),
|
||||
eventNotes: z.array(BareNote).nullable(),
|
||||
globalNotes: z.array(BareNote).nullable(),
|
||||
})
|
||||
);
|
||||
|
||||
|
@ -346,24 +402,14 @@ export const ImportTimelineResult = z.object({
|
|||
.optional(),
|
||||
});
|
||||
|
||||
export type ExportedTimelines = z.infer<typeof ExportedTimelines>;
|
||||
export const ExportedTimelines = SavedTimeline.merge(
|
||||
export type TimelineErrorResponse = z.infer<typeof TimelineErrorResponse>;
|
||||
export const TimelineErrorResponse = z.union([
|
||||
z.object({
|
||||
globalNotes: z.array(Note).optional(),
|
||||
eventNotes: z.array(Note).optional(),
|
||||
pinnedEventIds: z.array(z.string()).optional(),
|
||||
})
|
||||
);
|
||||
|
||||
export type Readable = z.infer<typeof Readable>;
|
||||
export const Readable = z.object({
|
||||
_maxListeners: z.object({}).catchall(z.unknown()).optional(),
|
||||
_readableState: z.object({}).catchall(z.unknown()).optional(),
|
||||
_read: z.object({}).catchall(z.unknown()).optional(),
|
||||
readable: z.boolean().optional(),
|
||||
_events: z.object({}).catchall(z.unknown()).optional(),
|
||||
_eventsCount: z.number().optional(),
|
||||
_data: z.object({}).catchall(z.unknown()).optional(),
|
||||
_position: z.number().optional(),
|
||||
_encoding: z.string().optional(),
|
||||
});
|
||||
message: z.string(),
|
||||
status_code: z.number(),
|
||||
}),
|
||||
z.object({
|
||||
message: z.string(),
|
||||
statusCode: z.number(),
|
||||
}),
|
||||
]);
|
||||
|
|
|
@ -56,11 +56,15 @@ components:
|
|||
end:
|
||||
oneOf:
|
||||
- type: string
|
||||
nullable: true
|
||||
- type: number
|
||||
nullable: true
|
||||
start:
|
||||
oneOf:
|
||||
- type: string
|
||||
nullable: true
|
||||
- type: number
|
||||
nullable: true
|
||||
description:
|
||||
type: string
|
||||
nullable: true
|
||||
|
@ -149,43 +153,73 @@ components:
|
|||
updatedBy:
|
||||
type: string
|
||||
nullable: true
|
||||
TimelineResponse:
|
||||
SavedTimelineWithSavedObjectId:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SavedTimeline'
|
||||
- type: object
|
||||
required:
|
||||
- savedObjectId
|
||||
- version
|
||||
required: [savedObjectId, version]
|
||||
properties:
|
||||
eventIdToNoteIds:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Note'
|
||||
notes:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Note'
|
||||
noteIds:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
pinnedEventIds:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
pinnedEventsSaveObject:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/PinnedEvent'
|
||||
savedObjectId:
|
||||
type: string
|
||||
version:
|
||||
type: string
|
||||
TimelineResponse:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SavedTimeline'
|
||||
- $ref: '#/components/schemas/SavedTimelineWithSavedObjectId'
|
||||
- type: object
|
||||
properties:
|
||||
eventIdToNoteIds:
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
$ref: '#/components/schemas/Note'
|
||||
notes:
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
$ref: '#/components/schemas/Note'
|
||||
noteIds:
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
type: string
|
||||
pinnedEventIds:
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
type: string
|
||||
pinnedEventsSaveObject:
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
$ref: '#/components/schemas/PinnedEvent'
|
||||
ResolvedTimeline:
|
||||
type: object
|
||||
required: [timeline, outcome]
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '#/components/schemas/TimelineSavedToReturnObject'
|
||||
outcome:
|
||||
$ref: '#/components/schemas/SavedObjectResolveOutcome'
|
||||
alias_target_id:
|
||||
type: string
|
||||
alias_purpose:
|
||||
$ref: '#/components/schemas/SavedObjectResolveAliasPurpose'
|
||||
SavedObjectResolveOutcome:
|
||||
type: string
|
||||
enum:
|
||||
- exactMatch
|
||||
- aliasMatch
|
||||
- conflict
|
||||
SavedObjectResolveAliasPurpose:
|
||||
type: string
|
||||
enum:
|
||||
- savedObjectConversion
|
||||
- savedObjectImport
|
||||
FavoriteTimelineResponse:
|
||||
type: object
|
||||
required:
|
||||
- savedObjectId
|
||||
- version
|
||||
required: [savedObjectId, version]
|
||||
properties:
|
||||
savedObjectId:
|
||||
type: string
|
||||
|
@ -209,35 +243,58 @@ components:
|
|||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/FavoriteTimelineResult'
|
||||
PersistTimelineResponse:
|
||||
type: object
|
||||
required: [data]
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
required: [persistTimeline]
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
required: [timeline]
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '#/components/schemas/TimelineResponse'
|
||||
ColumnHeaderResult:
|
||||
type: object
|
||||
properties:
|
||||
aggregatable:
|
||||
type: boolean
|
||||
nullable: true
|
||||
category:
|
||||
type: string
|
||||
nullable: true
|
||||
columnHeaderType:
|
||||
type: string
|
||||
nullable: true
|
||||
description:
|
||||
type: string
|
||||
nullable: true
|
||||
example:
|
||||
oneOf:
|
||||
- type: string
|
||||
- type: number
|
||||
type: string
|
||||
nullable: true
|
||||
indexes:
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
nullable: true
|
||||
name:
|
||||
type: string
|
||||
nullable: true
|
||||
placeholder:
|
||||
type: string
|
||||
nullable: true
|
||||
searchable:
|
||||
type: boolean
|
||||
nullable: true
|
||||
type:
|
||||
type: string
|
||||
nullable: true
|
||||
QueryMatchResult:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -248,8 +305,13 @@ components:
|
|||
type: string
|
||||
nullable: true
|
||||
value:
|
||||
type: string
|
||||
nullable: true
|
||||
oneOf:
|
||||
- type: string
|
||||
nullable: true
|
||||
- type: array
|
||||
nullable: true
|
||||
items:
|
||||
type: string
|
||||
displayValue:
|
||||
type: string
|
||||
nullable: true
|
||||
|
@ -305,6 +367,10 @@ components:
|
|||
nullable: true
|
||||
queryMatch:
|
||||
$ref: '#/components/schemas/QueryMatchResult'
|
||||
nullable: true
|
||||
type:
|
||||
$ref: '#/components/schemas/DataProviderType'
|
||||
nullable: true
|
||||
BareNoteWithoutExternalRefs:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -419,42 +485,60 @@ components:
|
|||
type: object
|
||||
properties:
|
||||
exists:
|
||||
type: boolean
|
||||
type: string
|
||||
nullable: true
|
||||
meta:
|
||||
type: object
|
||||
nullable: true
|
||||
properties:
|
||||
alias:
|
||||
type: string
|
||||
nullable: true
|
||||
controlledBy:
|
||||
type: string
|
||||
nullable: true
|
||||
disabled:
|
||||
type: boolean
|
||||
nullable: true
|
||||
field:
|
||||
type: string
|
||||
nullable: true
|
||||
formattedValue:
|
||||
type: string
|
||||
nullable: true
|
||||
index:
|
||||
type: string
|
||||
nullable: true
|
||||
key:
|
||||
type: string
|
||||
nullable: true
|
||||
negate:
|
||||
type: boolean
|
||||
nullable: true
|
||||
params:
|
||||
type: string
|
||||
nullable: true
|
||||
type:
|
||||
type: string
|
||||
nullable: true
|
||||
value:
|
||||
type: string
|
||||
nullable: true
|
||||
match_all:
|
||||
type: string
|
||||
nullable: true
|
||||
missing:
|
||||
type: string
|
||||
nullable: true
|
||||
query:
|
||||
type: string
|
||||
nullable: true
|
||||
range:
|
||||
type: string
|
||||
nullable: true
|
||||
script:
|
||||
type: string
|
||||
nullable: true
|
||||
SerializedFilterQueryResult:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -531,6 +615,11 @@ components:
|
|||
- description
|
||||
- updated
|
||||
- created
|
||||
SortDirection:
|
||||
type: string
|
||||
enum:
|
||||
- asc
|
||||
- desc
|
||||
TimelineStatus:
|
||||
type: string
|
||||
enum:
|
||||
|
@ -544,6 +633,7 @@ components:
|
|||
allOf:
|
||||
- $ref: '#/components/schemas/SavedTimeline'
|
||||
- type: object
|
||||
required: [savedObjectId, version, pinnedEventIds, eventNotes, globalNotes]
|
||||
properties:
|
||||
savedObjectId:
|
||||
type: string
|
||||
|
@ -551,21 +641,56 @@ components:
|
|||
version:
|
||||
type: string
|
||||
nullable: true
|
||||
globalNotes:
|
||||
nullable: true
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/BareNote'
|
||||
eventNotes:
|
||||
nullable: true
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/BareNote'
|
||||
pinnedEventIds:
|
||||
nullable: true
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
type: string
|
||||
eventNotes:
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
$ref: '#/components/schemas/BareNote'
|
||||
globalNotes:
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
$ref: '#/components/schemas/BareNote'
|
||||
TimelineSavedToReturnObject:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SavedTimeline'
|
||||
- type: object
|
||||
required: [savedObjectId, version]
|
||||
properties:
|
||||
savedObjectId:
|
||||
type: string
|
||||
version:
|
||||
type: string
|
||||
eventIdToNoteIds:
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
$ref: '#/components/schemas/Note'
|
||||
notes:
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
$ref: '#/components/schemas/Note'
|
||||
noteIds:
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
type: string
|
||||
pinnedEventIds:
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
type: string
|
||||
pinnedEventsSaveObject:
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
$ref: '#/components/schemas/PinnedEvent'
|
||||
ImportTimelineResult:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -591,46 +716,19 @@ components:
|
|||
type: string
|
||||
status_code:
|
||||
type: number
|
||||
ExportedTimelines:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SavedTimeline'
|
||||
TimelineErrorResponse:
|
||||
oneOf:
|
||||
- type: object
|
||||
required: [message, status_code]
|
||||
properties:
|
||||
globalNotes:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Note'
|
||||
eventNotes:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Note'
|
||||
pinnedEventIds:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
Readable:
|
||||
type: object
|
||||
properties:
|
||||
_maxListeners:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
_readableState:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
_read:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
readable:
|
||||
type: boolean
|
||||
_events:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
_eventsCount:
|
||||
type: number
|
||||
_data:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
_position:
|
||||
type: number
|
||||
_encoding:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
status_code:
|
||||
type: number
|
||||
- type: object
|
||||
required: [message, statusCode]
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
statusCode:
|
||||
type: number
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
import { SavedTimeline, TimelineResponse } from '../model/components.gen';
|
||||
import { SavedTimeline, PersistTimelineResponse } from '../model/components.gen';
|
||||
|
||||
export type PatchTimelineRequestBody = z.infer<typeof PatchTimelineRequestBody>;
|
||||
export const PatchTimelineRequestBody = z.object({
|
||||
|
@ -27,10 +27,4 @@ export const PatchTimelineRequestBody = z.object({
|
|||
export type PatchTimelineRequestBodyInput = z.input<typeof PatchTimelineRequestBody>;
|
||||
|
||||
export type PatchTimelineResponse = z.infer<typeof PatchTimelineResponse>;
|
||||
export const PatchTimelineResponse = z.object({
|
||||
data: z.object({
|
||||
persistTimeline: z.object({
|
||||
timeline: TimelineResponse,
|
||||
}),
|
||||
}),
|
||||
});
|
||||
export const PatchTimelineResponse = PersistTimelineResponse;
|
||||
|
|
|
@ -2,13 +2,6 @@ openapi: 3.0.0
|
|||
info:
|
||||
title: Elastic Security - Timeline - Patch Timeline API
|
||||
version: '2023-10-31'
|
||||
servers:
|
||||
- url: 'http://{kibana_host}:{port}'
|
||||
variables:
|
||||
kibana_host:
|
||||
default: localhost
|
||||
port:
|
||||
default: '5601'
|
||||
paths:
|
||||
/api/timeline:
|
||||
patch:
|
||||
|
@ -42,19 +35,7 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [data]
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
required: [persistTimeline]
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
required: [timeline]
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/TimelineResponse'
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/PersistTimelineResponse'
|
||||
'405':
|
||||
description: Indicates that the user does not have the required access to create a draft Timeline.
|
||||
content:
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import * as rt from 'io-ts';
|
||||
|
||||
import type { ResponseTimeline } from '../model/api';
|
||||
import { SavedTimelineRuntimeType } from '../model/api';
|
||||
import { unionWithNullType } from '../../../utility_types';
|
||||
|
||||
export const patchTimelineSchema = rt.type({
|
||||
timeline: SavedTimelineRuntimeType,
|
||||
timelineId: unionWithNullType(rt.string),
|
||||
version: unionWithNullType(rt.string),
|
||||
});
|
||||
|
||||
export interface PatchTimelinesResponse {
|
||||
data: {
|
||||
persistTimeline: ResponseTimeline;
|
||||
};
|
||||
}
|
|
@ -2,13 +2,6 @@ openapi: 3.0.0
|
|||
info:
|
||||
title: Elastic Security - Timeline - Favorite API
|
||||
version: '2023-10-31'
|
||||
servers:
|
||||
- url: 'http://{kibana_host}:{port}'
|
||||
variables:
|
||||
kibana_host:
|
||||
default: localhost
|
||||
port:
|
||||
default: '5601'
|
||||
paths:
|
||||
/api/timeline/_favorite:
|
||||
patch:
|
||||
|
|
|
@ -5,13 +5,6 @@ info:
|
|||
externalDocs:
|
||||
url: https://www.elastic.co/guide/en/security/current/timeline-api-update.html
|
||||
description: Documentation
|
||||
servers:
|
||||
- url: 'http://{kibana_host}:{port}'
|
||||
variables:
|
||||
kibana_host:
|
||||
default: localhost
|
||||
port:
|
||||
default: '5601'
|
||||
paths:
|
||||
/api/note:
|
||||
patch:
|
||||
|
|
|
@ -5,13 +5,6 @@ info:
|
|||
externalDocs:
|
||||
url: https://www.elastic.co/guide/en/security/current/_pin_an_event_to_an_existing_timeline.html
|
||||
description: Documentation
|
||||
servers:
|
||||
- url: 'http://{kibana_host}:{port}'
|
||||
variables:
|
||||
kibana_host:
|
||||
default: localhost
|
||||
port:
|
||||
default: '5601'
|
||||
paths:
|
||||
/api/pinned_event:
|
||||
patch:
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import * as runtimeTypes from 'io-ts';
|
||||
import { unionWithNullType } from '../../../utility_types';
|
||||
|
||||
/*
|
||||
* Pinned Event Types
|
||||
* TODO: remove these when the timeline types are moved to zod
|
||||
*/
|
||||
const BarePinnedEventType = runtimeTypes.intersection([
|
||||
runtimeTypes.type({
|
||||
timelineId: runtimeTypes.string,
|
||||
eventId: runtimeTypes.string,
|
||||
}),
|
||||
runtimeTypes.partial({
|
||||
created: unionWithNullType(runtimeTypes.number),
|
||||
createdBy: unionWithNullType(runtimeTypes.string),
|
||||
updated: unionWithNullType(runtimeTypes.number),
|
||||
updatedBy: unionWithNullType(runtimeTypes.string),
|
||||
}),
|
||||
]);
|
||||
|
||||
export const PinnedEventRuntimeType = runtimeTypes.intersection([
|
||||
runtimeTypes.type({
|
||||
pinnedEventId: runtimeTypes.string,
|
||||
version: runtimeTypes.string,
|
||||
}),
|
||||
BarePinnedEventType,
|
||||
]);
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
import { z } from '@kbn/zod';
|
||||
|
||||
import { TimelineResponse } from '../model/components.gen';
|
||||
import { ResolvedTimeline } from '../model/components.gen';
|
||||
|
||||
export type ResolveTimelineRequestQuery = z.infer<typeof ResolveTimelineRequestQuery>;
|
||||
export const ResolveTimelineRequestQuery = z.object({
|
||||
|
@ -32,8 +32,9 @@ export const ResolveTimelineRequestQuery = z.object({
|
|||
export type ResolveTimelineRequestQueryInput = z.input<typeof ResolveTimelineRequestQuery>;
|
||||
|
||||
export type ResolveTimelineResponse = z.infer<typeof ResolveTimelineResponse>;
|
||||
export const ResolveTimelineResponse = z.object({
|
||||
data: z.object({
|
||||
getOneTimeline: TimelineResponse.nullable(),
|
||||
export const ResolveTimelineResponse = z.union([
|
||||
z.object({
|
||||
data: ResolvedTimeline,
|
||||
}),
|
||||
});
|
||||
z.object({}).strict(),
|
||||
]);
|
||||
|
|
|
@ -2,13 +2,6 @@ openapi: 3.0.0
|
|||
info:
|
||||
title: Elastic Security - Timeline - Resolve Timeline API
|
||||
version: '2023-10-31'
|
||||
servers:
|
||||
- url: 'http://{kibana_host}:{port}'
|
||||
variables:
|
||||
kibana_host:
|
||||
default: localhost
|
||||
port:
|
||||
default: '5601'
|
||||
paths:
|
||||
/api/timeline/resolve:
|
||||
get:
|
||||
|
@ -35,16 +28,15 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [data]
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
required: [getOneTimeline]
|
||||
oneOf:
|
||||
- type: object
|
||||
required: [data]
|
||||
properties:
|
||||
getOneTimeline:
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/TimelineResponse'
|
||||
nullable: true
|
||||
data:
|
||||
$ref: '../model/components.schema.yaml#/components/schemas/ResolvedTimeline'
|
||||
- type: object
|
||||
additionalProperties: false
|
||||
|
||||
'400':
|
||||
description: The request is missing parameters
|
||||
'404':
|
||||
|
|
|
@ -17,7 +17,10 @@ export {
|
|||
} from './persist_note/persist_note_route.gen';
|
||||
export { DeleteNoteRequestBody, DeleteNoteResponse } from './delete_note/delete_note_route.gen';
|
||||
|
||||
export { CleanDraftTimelinesRequestBody } from './clean_draft_timelines/clean_draft_timelines_route.gen';
|
||||
export {
|
||||
CleanDraftTimelinesResponse,
|
||||
CleanDraftTimelinesRequestBody,
|
||||
} from './clean_draft_timelines/clean_draft_timelines_route.gen';
|
||||
|
||||
export {
|
||||
ExportTimelinesRequestQuery,
|
||||
|
@ -40,3 +43,48 @@ export {
|
|||
GetNotesResponse,
|
||||
GetNotesResult,
|
||||
} from './get_notes/get_notes_route.gen';
|
||||
|
||||
export {
|
||||
CopyTimelineRequestBody,
|
||||
CopyTimelineResponse,
|
||||
} from './copy_timeline/copy_timeline_route.gen';
|
||||
|
||||
export {
|
||||
CreateTimelinesRequestBody,
|
||||
CreateTimelinesResponse,
|
||||
} from './create_timelines/create_timelines_route.gen';
|
||||
|
||||
export {
|
||||
PatchTimelineRequestBody,
|
||||
PatchTimelineResponse,
|
||||
} from './patch_timelines/patch_timeline_route.gen';
|
||||
|
||||
export {
|
||||
ImportTimelinesRequestBody,
|
||||
ImportTimelinesResponse,
|
||||
} from './import_timelines/import_timelines_route.gen';
|
||||
|
||||
export {
|
||||
InstallPrepackedTimelinesRequestBody,
|
||||
InstallPrepackedTimelinesResponse,
|
||||
} from './install_prepackaged_timelines/install_prepackaged_timelines_route.gen';
|
||||
|
||||
export {
|
||||
GetDraftTimelinesRequestQuery,
|
||||
GetDraftTimelinesResponse,
|
||||
} from './get_draft_timelines/get_draft_timelines_route.gen';
|
||||
|
||||
export {
|
||||
ResolveTimelineRequestQuery,
|
||||
ResolveTimelineResponse,
|
||||
} from './resolve_timeline/resolve_timeline_route.gen';
|
||||
|
||||
export {
|
||||
GetTimelineRequestQuery,
|
||||
GetTimelineResponse,
|
||||
} from './get_timeline/get_timeline_route.gen';
|
||||
|
||||
export {
|
||||
GetTimelinesRequestQuery,
|
||||
GetTimelinesResponse,
|
||||
} from './get_timelines/get_timelines_route.gen';
|
||||
|
|
|
@ -5,13 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { SortField, Maybe } from '../common';
|
||||
import type {
|
||||
DataProviderType,
|
||||
TimelineType,
|
||||
TimelineStatus,
|
||||
RowRendererId,
|
||||
} from '../../api/timeline';
|
||||
import type { SortField } from '../common';
|
||||
|
||||
export * from './events';
|
||||
|
||||
|
@ -20,122 +14,6 @@ export interface TimelineRequestSortField<Field = string> extends SortField<Fiel
|
|||
esTypes: string[];
|
||||
}
|
||||
|
||||
export interface ColumnHeaderInput {
|
||||
aggregatable?: Maybe<boolean>;
|
||||
category?: Maybe<string>;
|
||||
columnHeaderType?: Maybe<string>;
|
||||
description?: Maybe<string>;
|
||||
example?: Maybe<string>;
|
||||
indexes?: Maybe<string[]>;
|
||||
id?: Maybe<string>;
|
||||
name?: Maybe<string>;
|
||||
placeholder?: Maybe<string>;
|
||||
searchable?: Maybe<boolean>;
|
||||
type?: Maybe<string>;
|
||||
}
|
||||
|
||||
export interface QueryMatchInput {
|
||||
field?: Maybe<string>;
|
||||
|
||||
displayField?: Maybe<string>;
|
||||
|
||||
value?: Maybe<string>;
|
||||
|
||||
displayValue?: Maybe<string>;
|
||||
|
||||
operator?: Maybe<string>;
|
||||
}
|
||||
|
||||
export interface DataProviderInput {
|
||||
id?: Maybe<string>;
|
||||
name?: Maybe<string>;
|
||||
enabled?: Maybe<boolean>;
|
||||
excluded?: Maybe<boolean>;
|
||||
kqlQuery?: Maybe<string>;
|
||||
queryMatch?: Maybe<QueryMatchInput>;
|
||||
and?: Maybe<DataProviderInput[]>;
|
||||
type?: Maybe<DataProviderType>;
|
||||
}
|
||||
|
||||
export interface EqlOptionsInput {
|
||||
eventCategoryField?: Maybe<string>;
|
||||
tiebreakerField?: Maybe<string>;
|
||||
timestampField?: Maybe<string>;
|
||||
query?: Maybe<string>;
|
||||
size?: Maybe<number>;
|
||||
}
|
||||
|
||||
export interface FilterMetaTimelineInput {
|
||||
alias?: Maybe<string>;
|
||||
controlledBy?: Maybe<string>;
|
||||
disabled?: Maybe<boolean>;
|
||||
field?: Maybe<string>;
|
||||
formattedValue?: Maybe<string>;
|
||||
index?: Maybe<string>;
|
||||
key?: Maybe<string>;
|
||||
negate?: Maybe<boolean>;
|
||||
params?: Maybe<string>;
|
||||
type?: Maybe<string>;
|
||||
value?: Maybe<string>;
|
||||
}
|
||||
|
||||
export interface FilterTimelineInput {
|
||||
exists?: Maybe<string>;
|
||||
meta?: Maybe<FilterMetaTimelineInput>;
|
||||
match_all?: Maybe<string>;
|
||||
missing?: Maybe<string>;
|
||||
query?: Maybe<string>;
|
||||
range?: Maybe<string>;
|
||||
script?: Maybe<string>;
|
||||
}
|
||||
|
||||
export interface SerializedFilterQueryInput {
|
||||
filterQuery?: Maybe<SerializedKueryQueryInput>;
|
||||
}
|
||||
|
||||
export interface SerializedKueryQueryInput {
|
||||
kuery?: Maybe<KueryFilterQueryInput>;
|
||||
serializedQuery?: Maybe<string>;
|
||||
}
|
||||
|
||||
export interface KueryFilterQueryInput {
|
||||
kind?: Maybe<string>;
|
||||
expression?: Maybe<string>;
|
||||
}
|
||||
|
||||
export interface DateRangePickerInput {
|
||||
start?: Maybe<number>;
|
||||
end?: Maybe<number>;
|
||||
}
|
||||
|
||||
export interface SortTimelineInput {
|
||||
columnId?: Maybe<string>;
|
||||
sortDirection?: Maybe<string>;
|
||||
}
|
||||
|
||||
export interface TimelineInput {
|
||||
columns?: Maybe<ColumnHeaderInput[]>;
|
||||
dataProviders?: Maybe<DataProviderInput[]>;
|
||||
dataViewId?: Maybe<string>;
|
||||
description?: Maybe<string>;
|
||||
eqlOptions?: Maybe<EqlOptionsInput>;
|
||||
eventType?: Maybe<string>;
|
||||
excludedRowRendererIds?: Maybe<RowRendererId[]>;
|
||||
filters?: Maybe<FilterTimelineInput[]>;
|
||||
kqlMode?: Maybe<string>;
|
||||
kqlQuery?: Maybe<SerializedFilterQueryInput>;
|
||||
indexNames?: Maybe<string[]>;
|
||||
title?: Maybe<string>;
|
||||
templateTimelineId?: Maybe<string>;
|
||||
templateTimelineVersion?: Maybe<number>;
|
||||
timelineType?: Maybe<TimelineType>;
|
||||
dateRange?: Maybe<DateRangePickerInput>;
|
||||
savedQueryId?: Maybe<string>;
|
||||
sort?: Maybe<SortTimelineInput[]>;
|
||||
status?: Maybe<TimelineStatus>;
|
||||
savedSearchId: Maybe<string>;
|
||||
}
|
||||
|
||||
export enum FlowDirection {
|
||||
uniDirectional = 'uniDirectional',
|
||||
biDirectional = 'biDirectional',
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { ZodError, ZodType } from '@kbn/zod';
|
||||
import { stringifyZodError } from '@kbn/zod-helpers';
|
||||
import { type Either, fold, left, right } from 'fp-ts/lib/Either';
|
||||
import { identity } from 'fp-ts/lib/function';
|
||||
import { pipe } from 'fp-ts/lib/pipeable';
|
||||
|
||||
type ErrorFactory = (message: string) => Error;
|
||||
|
||||
const throwErrors = (createError: ErrorFactory) => (errors: ZodError) => {
|
||||
throw createError(stringifyZodError(errors));
|
||||
};
|
||||
|
||||
const parseRuntimeType =
|
||||
<T>(zodType: ZodType<T>) =>
|
||||
(v: unknown): Either<ZodError<T>, T> => {
|
||||
const result = zodType.safeParse(v);
|
||||
return result.success ? right(result.data) : left(result.error);
|
||||
};
|
||||
|
||||
export const parseOrThrowErrorFactory =
|
||||
(createError: ErrorFactory) => (runtimeType: ZodType) => (inputValue: unknown) =>
|
||||
pipe(parseRuntimeType(runtimeType)(inputValue), fold(throwErrors(createError), identity));
|
|
@ -268,18 +268,20 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
oneOf:
|
||||
- type: object
|
||||
properties:
|
||||
getOneTimeline:
|
||||
$ref: '#/components/schemas/TimelineResponse'
|
||||
nullable: true
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
getOneTimeline:
|
||||
$ref: '#/components/schemas/TimelineResponse'
|
||||
required:
|
||||
- getOneTimeline
|
||||
required:
|
||||
- getOneTimeline
|
||||
required:
|
||||
- data
|
||||
- data
|
||||
- additionalProperties: false
|
||||
type: object
|
||||
description: Indicates that the (template) Timeline was found and returned.
|
||||
summary: Get Timeline or Timeline template details
|
||||
tags:
|
||||
|
@ -316,22 +318,7 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '#/components/schemas/TimelineResponse'
|
||||
required:
|
||||
- timeline
|
||||
required:
|
||||
- persistTimeline
|
||||
required:
|
||||
- data
|
||||
$ref: '#/components/schemas/PersistTimelineResponse'
|
||||
description: >-
|
||||
Indicates that the draft Timeline was successfully created. In the
|
||||
event the user already has a draft Timeline, the existing draft
|
||||
|
@ -393,20 +380,7 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '#/components/schemas/TimelineResponse'
|
||||
required:
|
||||
- persistTimeline
|
||||
required:
|
||||
- data
|
||||
$ref: '#/components/schemas/PersistTimelineResponse'
|
||||
description: Indicates the Timeline was successfully created.
|
||||
'405':
|
||||
content:
|
||||
|
@ -423,6 +397,36 @@ paths:
|
|||
tags:
|
||||
- Security Timeline API
|
||||
- access:securitySolution
|
||||
/api/timeline/_copy:
|
||||
get:
|
||||
description: |
|
||||
Copies and returns a timeline or timeline template.
|
||||
operationId: CopyTimeline
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '#/components/schemas/SavedTimeline'
|
||||
timelineIdToCopy:
|
||||
type: string
|
||||
required:
|
||||
- timeline
|
||||
- timelineIdToCopy
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PersistTimelineResponse'
|
||||
description: Indicates that the timeline has been successfully copied.
|
||||
summary: Copies timeline or timeline template
|
||||
tags:
|
||||
- Security Timeline API
|
||||
- access:securitySolution
|
||||
/api/timeline/_draft:
|
||||
get:
|
||||
description: >-
|
||||
|
@ -441,22 +445,7 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '#/components/schemas/TimelineResponse'
|
||||
required:
|
||||
- timeline
|
||||
required:
|
||||
- persistTimeline
|
||||
required:
|
||||
- data
|
||||
$ref: '#/components/schemas/PersistTimelineResponse'
|
||||
description: Indicates that the draft Timeline was successfully retrieved.
|
||||
'403':
|
||||
content:
|
||||
|
@ -518,22 +507,7 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '#/components/schemas/TimelineResponse'
|
||||
required:
|
||||
- timeline
|
||||
required:
|
||||
- persistTimeline
|
||||
required:
|
||||
- data
|
||||
$ref: '#/components/schemas/PersistTimelineResponse'
|
||||
description: >-
|
||||
Indicates that the draft Timeline was successfully created. In the
|
||||
event the user already has a draft Timeline, the existing draft
|
||||
|
@ -688,28 +662,14 @@ paths:
|
|||
schema:
|
||||
type: object
|
||||
properties:
|
||||
file:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Readable'
|
||||
- type: object
|
||||
properties:
|
||||
hapi:
|
||||
type: object
|
||||
properties:
|
||||
filename:
|
||||
type: string
|
||||
headers:
|
||||
type: object
|
||||
isImmutable:
|
||||
enum:
|
||||
- 'true'
|
||||
- 'false'
|
||||
type: string
|
||||
required:
|
||||
- filename
|
||||
- headers
|
||||
required:
|
||||
- hapi
|
||||
file: {}
|
||||
isImmutable:
|
||||
enum:
|
||||
- 'true'
|
||||
- 'false'
|
||||
type: string
|
||||
required:
|
||||
- file
|
||||
description: The Timelines to import as a readable stream.
|
||||
required: true
|
||||
responses:
|
||||
|
@ -717,12 +677,7 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/ImportTimelineResult'
|
||||
required:
|
||||
- data
|
||||
$ref: '#/components/schemas/ImportTimelineResult'
|
||||
description: Indicates the import of Timelines was successful.
|
||||
'400':
|
||||
content:
|
||||
|
@ -781,7 +736,8 @@ paths:
|
|||
properties:
|
||||
prepackagedTimelines:
|
||||
items:
|
||||
$ref: '#/components/schemas/SavedTimeline'
|
||||
$ref: '#/components/schemas/TimelineSavedToReturnObject'
|
||||
nullable: true
|
||||
type: array
|
||||
timelinesToInstall:
|
||||
items:
|
||||
|
@ -804,12 +760,7 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/ImportTimelineResult'
|
||||
required:
|
||||
- data
|
||||
$ref: '#/components/schemas/ImportTimelineResult'
|
||||
description: Indicates the installation of prepackaged Timelines was successful.
|
||||
'500':
|
||||
content:
|
||||
|
@ -847,18 +798,15 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
oneOf:
|
||||
- type: object
|
||||
properties:
|
||||
getOneTimeline:
|
||||
$ref: '#/components/schemas/TimelineResponse'
|
||||
nullable: true
|
||||
data:
|
||||
$ref: '#/components/schemas/ResolvedTimeline'
|
||||
required:
|
||||
- getOneTimeline
|
||||
required:
|
||||
- data
|
||||
- data
|
||||
- additionalProperties: false
|
||||
type: object
|
||||
description: The (template) Timeline has been found
|
||||
'400':
|
||||
description: The request is missing parameters
|
||||
|
@ -927,35 +875,25 @@ paths:
|
|||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
customTemplateTimelineCount:
|
||||
type: number
|
||||
defaultTimelineCount:
|
||||
type: number
|
||||
elasticTemplateTimelineCount:
|
||||
type: number
|
||||
favoriteCount:
|
||||
type: number
|
||||
templateTimelineCount:
|
||||
type: number
|
||||
timelines:
|
||||
items:
|
||||
$ref: '#/components/schemas/TimelineResponse'
|
||||
type: array
|
||||
totalCount:
|
||||
type: number
|
||||
required:
|
||||
- timelines
|
||||
- totalCount
|
||||
- defaultTimelineCount
|
||||
- templateTimelineCount
|
||||
- favoriteCount
|
||||
- elasticTemplateTimelineCount
|
||||
- customTemplateTimelineCount
|
||||
customTemplateTimelineCount:
|
||||
type: number
|
||||
defaultTimelineCount:
|
||||
type: number
|
||||
elasticTemplateTimelineCount:
|
||||
type: number
|
||||
favoriteCount:
|
||||
type: number
|
||||
templateTimelineCount:
|
||||
type: number
|
||||
timeline:
|
||||
items:
|
||||
$ref: '#/components/schemas/TimelineResponse'
|
||||
type: array
|
||||
totalCount:
|
||||
type: number
|
||||
required:
|
||||
- data
|
||||
- timeline
|
||||
- totalCount
|
||||
description: Indicates that the (template) Timelines were found and returned.
|
||||
'400':
|
||||
content:
|
||||
|
@ -1025,30 +963,39 @@ components:
|
|||
type: object
|
||||
properties:
|
||||
aggregatable:
|
||||
nullable: true
|
||||
type: boolean
|
||||
category:
|
||||
nullable: true
|
||||
type: string
|
||||
columnHeaderType:
|
||||
nullable: true
|
||||
type: string
|
||||
description:
|
||||
nullable: true
|
||||
type: string
|
||||
example:
|
||||
oneOf:
|
||||
- type: string
|
||||
- type: number
|
||||
nullable: true
|
||||
type: string
|
||||
id:
|
||||
nullable: true
|
||||
type: string
|
||||
indexes:
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
name:
|
||||
nullable: true
|
||||
type: string
|
||||
placeholder:
|
||||
nullable: true
|
||||
type: string
|
||||
searchable:
|
||||
nullable: true
|
||||
type: boolean
|
||||
type:
|
||||
nullable: true
|
||||
type: string
|
||||
DataProviderQueryMatch:
|
||||
type: object
|
||||
|
@ -1070,6 +1017,10 @@ components:
|
|||
type: string
|
||||
queryMatch:
|
||||
$ref: '#/components/schemas/QueryMatchResult'
|
||||
nullable: true
|
||||
type:
|
||||
$ref: '#/components/schemas/DataProviderType'
|
||||
nullable: true
|
||||
DataProviderResult:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -1157,41 +1108,59 @@ components:
|
|||
type: object
|
||||
properties:
|
||||
exists:
|
||||
type: boolean
|
||||
nullable: true
|
||||
type: string
|
||||
match_all:
|
||||
nullable: true
|
||||
type: string
|
||||
meta:
|
||||
nullable: true
|
||||
type: object
|
||||
properties:
|
||||
alias:
|
||||
nullable: true
|
||||
type: string
|
||||
controlledBy:
|
||||
nullable: true
|
||||
type: string
|
||||
disabled:
|
||||
nullable: true
|
||||
type: boolean
|
||||
field:
|
||||
nullable: true
|
||||
type: string
|
||||
formattedValue:
|
||||
nullable: true
|
||||
type: string
|
||||
index:
|
||||
nullable: true
|
||||
type: string
|
||||
key:
|
||||
nullable: true
|
||||
type: string
|
||||
negate:
|
||||
nullable: true
|
||||
type: boolean
|
||||
params:
|
||||
nullable: true
|
||||
type: string
|
||||
type:
|
||||
nullable: true
|
||||
type: string
|
||||
value:
|
||||
nullable: true
|
||||
type: string
|
||||
missing:
|
||||
nullable: true
|
||||
type: string
|
||||
query:
|
||||
nullable: true
|
||||
type: string
|
||||
range:
|
||||
nullable: true
|
||||
type: string
|
||||
script:
|
||||
nullable: true
|
||||
type: string
|
||||
GetNotesResult:
|
||||
type: object
|
||||
|
@ -1256,6 +1225,12 @@ components:
|
|||
version:
|
||||
nullable: true
|
||||
type: string
|
||||
required:
|
||||
- savedObjectId
|
||||
- version
|
||||
- pinnedEventIds
|
||||
- eventNotes
|
||||
- globalNotes
|
||||
Note:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/BareNote'
|
||||
|
@ -1275,6 +1250,23 @@ components:
|
|||
- $ref: '#/components/schemas/PinnedEventBaseResponseBody'
|
||||
- nullable: true
|
||||
type: object
|
||||
PersistTimelineResponse:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '#/components/schemas/TimelineResponse'
|
||||
required:
|
||||
- timeline
|
||||
required:
|
||||
- persistTimeline
|
||||
required:
|
||||
- data
|
||||
PinnedEvent:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/BarePinnedEvent'
|
||||
|
@ -1312,34 +1304,27 @@ components:
|
|||
nullable: true
|
||||
type: string
|
||||
value:
|
||||
nullable: true
|
||||
type: string
|
||||
Readable:
|
||||
oneOf:
|
||||
- nullable: true
|
||||
type: string
|
||||
- items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
ResolvedTimeline:
|
||||
type: object
|
||||
properties:
|
||||
_data:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
_encoding:
|
||||
alias_purpose:
|
||||
$ref: '#/components/schemas/SavedObjectResolveAliasPurpose'
|
||||
alias_target_id:
|
||||
type: string
|
||||
_events:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
_eventsCount:
|
||||
type: number
|
||||
_maxListeners:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
_position:
|
||||
type: number
|
||||
_read:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
_readableState:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
readable:
|
||||
type: boolean
|
||||
outcome:
|
||||
$ref: '#/components/schemas/SavedObjectResolveOutcome'
|
||||
timeline:
|
||||
$ref: '#/components/schemas/TimelineSavedToReturnObject'
|
||||
required:
|
||||
- timeline
|
||||
- outcome
|
||||
ResponseNote:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -1374,6 +1359,17 @@ components:
|
|||
- threat_match
|
||||
- zeek
|
||||
type: string
|
||||
SavedObjectResolveAliasPurpose:
|
||||
enum:
|
||||
- savedObjectConversion
|
||||
- savedObjectImport
|
||||
type: string
|
||||
SavedObjectResolveOutcome:
|
||||
enum:
|
||||
- exactMatch
|
||||
- aliasMatch
|
||||
- conflict
|
||||
type: string
|
||||
SavedTimeline:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -1402,12 +1398,16 @@ components:
|
|||
properties:
|
||||
end:
|
||||
oneOf:
|
||||
- type: string
|
||||
- type: number
|
||||
- nullable: true
|
||||
type: string
|
||||
- nullable: true
|
||||
type: number
|
||||
start:
|
||||
oneOf:
|
||||
- type: string
|
||||
- type: number
|
||||
- nullable: true
|
||||
type: string
|
||||
- nullable: true
|
||||
type: number
|
||||
description:
|
||||
nullable: true
|
||||
type: string
|
||||
|
@ -1496,6 +1496,18 @@ components:
|
|||
updatedBy:
|
||||
nullable: true
|
||||
type: string
|
||||
SavedTimelineWithSavedObjectId:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SavedTimeline'
|
||||
- type: object
|
||||
properties:
|
||||
savedObjectId:
|
||||
type: string
|
||||
version:
|
||||
type: string
|
||||
required:
|
||||
- savedObjectId
|
||||
- version
|
||||
SerializedFilterQueryResult:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -1545,27 +1557,63 @@ components:
|
|||
TimelineResponse:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SavedTimeline'
|
||||
- $ref: '#/components/schemas/SavedTimelineWithSavedObjectId'
|
||||
- type: object
|
||||
properties:
|
||||
eventIdToNoteIds:
|
||||
items:
|
||||
$ref: '#/components/schemas/Note'
|
||||
nullable: true
|
||||
type: array
|
||||
noteIds:
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
notes:
|
||||
items:
|
||||
$ref: '#/components/schemas/Note'
|
||||
nullable: true
|
||||
type: array
|
||||
pinnedEventIds:
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
pinnedEventsSaveObject:
|
||||
items:
|
||||
$ref: '#/components/schemas/PinnedEvent'
|
||||
nullable: true
|
||||
type: array
|
||||
TimelineSavedToReturnObject:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SavedTimeline'
|
||||
- type: object
|
||||
properties:
|
||||
eventIdToNoteIds:
|
||||
items:
|
||||
$ref: '#/components/schemas/Note'
|
||||
nullable: true
|
||||
type: array
|
||||
noteIds:
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
notes:
|
||||
items:
|
||||
$ref: '#/components/schemas/Note'
|
||||
nullable: true
|
||||
type: array
|
||||
pinnedEventIds:
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
pinnedEventsSaveObject:
|
||||
items:
|
||||
$ref: '#/components/schemas/PinnedEvent'
|
||||
nullable: true
|
||||
type: array
|
||||
savedObjectId:
|
||||
type: string
|
||||
|
|
|
@ -268,18 +268,20 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
oneOf:
|
||||
- type: object
|
||||
properties:
|
||||
getOneTimeline:
|
||||
$ref: '#/components/schemas/TimelineResponse'
|
||||
nullable: true
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
getOneTimeline:
|
||||
$ref: '#/components/schemas/TimelineResponse'
|
||||
required:
|
||||
- getOneTimeline
|
||||
required:
|
||||
- getOneTimeline
|
||||
required:
|
||||
- data
|
||||
- data
|
||||
- additionalProperties: false
|
||||
type: object
|
||||
description: Indicates that the (template) Timeline was found and returned.
|
||||
summary: Get Timeline or Timeline template details
|
||||
tags:
|
||||
|
@ -316,22 +318,7 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '#/components/schemas/TimelineResponse'
|
||||
required:
|
||||
- timeline
|
||||
required:
|
||||
- persistTimeline
|
||||
required:
|
||||
- data
|
||||
$ref: '#/components/schemas/PersistTimelineResponse'
|
||||
description: >-
|
||||
Indicates that the draft Timeline was successfully created. In the
|
||||
event the user already has a draft Timeline, the existing draft
|
||||
|
@ -393,20 +380,7 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '#/components/schemas/TimelineResponse'
|
||||
required:
|
||||
- persistTimeline
|
||||
required:
|
||||
- data
|
||||
$ref: '#/components/schemas/PersistTimelineResponse'
|
||||
description: Indicates the Timeline was successfully created.
|
||||
'405':
|
||||
content:
|
||||
|
@ -423,6 +397,36 @@ paths:
|
|||
tags:
|
||||
- Security Timeline API
|
||||
- access:securitySolution
|
||||
/api/timeline/_copy:
|
||||
get:
|
||||
description: |
|
||||
Copies and returns a timeline or timeline template.
|
||||
operationId: CopyTimeline
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '#/components/schemas/SavedTimeline'
|
||||
timelineIdToCopy:
|
||||
type: string
|
||||
required:
|
||||
- timeline
|
||||
- timelineIdToCopy
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PersistTimelineResponse'
|
||||
description: Indicates that the timeline has been successfully copied.
|
||||
summary: Copies timeline or timeline template
|
||||
tags:
|
||||
- Security Timeline API
|
||||
- access:securitySolution
|
||||
/api/timeline/_draft:
|
||||
get:
|
||||
description: >-
|
||||
|
@ -441,22 +445,7 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '#/components/schemas/TimelineResponse'
|
||||
required:
|
||||
- timeline
|
||||
required:
|
||||
- persistTimeline
|
||||
required:
|
||||
- data
|
||||
$ref: '#/components/schemas/PersistTimelineResponse'
|
||||
description: Indicates that the draft Timeline was successfully retrieved.
|
||||
'403':
|
||||
content:
|
||||
|
@ -518,22 +507,7 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '#/components/schemas/TimelineResponse'
|
||||
required:
|
||||
- timeline
|
||||
required:
|
||||
- persistTimeline
|
||||
required:
|
||||
- data
|
||||
$ref: '#/components/schemas/PersistTimelineResponse'
|
||||
description: >-
|
||||
Indicates that the draft Timeline was successfully created. In the
|
||||
event the user already has a draft Timeline, the existing draft
|
||||
|
@ -688,28 +662,14 @@ paths:
|
|||
schema:
|
||||
type: object
|
||||
properties:
|
||||
file:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Readable'
|
||||
- type: object
|
||||
properties:
|
||||
hapi:
|
||||
type: object
|
||||
properties:
|
||||
filename:
|
||||
type: string
|
||||
headers:
|
||||
type: object
|
||||
isImmutable:
|
||||
enum:
|
||||
- 'true'
|
||||
- 'false'
|
||||
type: string
|
||||
required:
|
||||
- filename
|
||||
- headers
|
||||
required:
|
||||
- hapi
|
||||
file: {}
|
||||
isImmutable:
|
||||
enum:
|
||||
- 'true'
|
||||
- 'false'
|
||||
type: string
|
||||
required:
|
||||
- file
|
||||
description: The Timelines to import as a readable stream.
|
||||
required: true
|
||||
responses:
|
||||
|
@ -717,12 +677,7 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/ImportTimelineResult'
|
||||
required:
|
||||
- data
|
||||
$ref: '#/components/schemas/ImportTimelineResult'
|
||||
description: Indicates the import of Timelines was successful.
|
||||
'400':
|
||||
content:
|
||||
|
@ -781,7 +736,8 @@ paths:
|
|||
properties:
|
||||
prepackagedTimelines:
|
||||
items:
|
||||
$ref: '#/components/schemas/SavedTimeline'
|
||||
$ref: '#/components/schemas/TimelineSavedToReturnObject'
|
||||
nullable: true
|
||||
type: array
|
||||
timelinesToInstall:
|
||||
items:
|
||||
|
@ -804,12 +760,7 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/ImportTimelineResult'
|
||||
required:
|
||||
- data
|
||||
$ref: '#/components/schemas/ImportTimelineResult'
|
||||
description: Indicates the installation of prepackaged Timelines was successful.
|
||||
'500':
|
||||
content:
|
||||
|
@ -847,18 +798,15 @@ paths:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
oneOf:
|
||||
- type: object
|
||||
properties:
|
||||
getOneTimeline:
|
||||
$ref: '#/components/schemas/TimelineResponse'
|
||||
nullable: true
|
||||
data:
|
||||
$ref: '#/components/schemas/ResolvedTimeline'
|
||||
required:
|
||||
- getOneTimeline
|
||||
required:
|
||||
- data
|
||||
- data
|
||||
- additionalProperties: false
|
||||
type: object
|
||||
description: The (template) Timeline has been found
|
||||
'400':
|
||||
description: The request is missing parameters
|
||||
|
@ -927,35 +875,25 @@ paths:
|
|||
schema:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
customTemplateTimelineCount:
|
||||
type: number
|
||||
defaultTimelineCount:
|
||||
type: number
|
||||
elasticTemplateTimelineCount:
|
||||
type: number
|
||||
favoriteCount:
|
||||
type: number
|
||||
templateTimelineCount:
|
||||
type: number
|
||||
timelines:
|
||||
items:
|
||||
$ref: '#/components/schemas/TimelineResponse'
|
||||
type: array
|
||||
totalCount:
|
||||
type: number
|
||||
required:
|
||||
- timelines
|
||||
- totalCount
|
||||
- defaultTimelineCount
|
||||
- templateTimelineCount
|
||||
- favoriteCount
|
||||
- elasticTemplateTimelineCount
|
||||
- customTemplateTimelineCount
|
||||
customTemplateTimelineCount:
|
||||
type: number
|
||||
defaultTimelineCount:
|
||||
type: number
|
||||
elasticTemplateTimelineCount:
|
||||
type: number
|
||||
favoriteCount:
|
||||
type: number
|
||||
templateTimelineCount:
|
||||
type: number
|
||||
timeline:
|
||||
items:
|
||||
$ref: '#/components/schemas/TimelineResponse'
|
||||
type: array
|
||||
totalCount:
|
||||
type: number
|
||||
required:
|
||||
- data
|
||||
- timeline
|
||||
- totalCount
|
||||
description: Indicates that the (template) Timelines were found and returned.
|
||||
'400':
|
||||
content:
|
||||
|
@ -1025,30 +963,39 @@ components:
|
|||
type: object
|
||||
properties:
|
||||
aggregatable:
|
||||
nullable: true
|
||||
type: boolean
|
||||
category:
|
||||
nullable: true
|
||||
type: string
|
||||
columnHeaderType:
|
||||
nullable: true
|
||||
type: string
|
||||
description:
|
||||
nullable: true
|
||||
type: string
|
||||
example:
|
||||
oneOf:
|
||||
- type: string
|
||||
- type: number
|
||||
nullable: true
|
||||
type: string
|
||||
id:
|
||||
nullable: true
|
||||
type: string
|
||||
indexes:
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
name:
|
||||
nullable: true
|
||||
type: string
|
||||
placeholder:
|
||||
nullable: true
|
||||
type: string
|
||||
searchable:
|
||||
nullable: true
|
||||
type: boolean
|
||||
type:
|
||||
nullable: true
|
||||
type: string
|
||||
DataProviderQueryMatch:
|
||||
type: object
|
||||
|
@ -1070,6 +1017,10 @@ components:
|
|||
type: string
|
||||
queryMatch:
|
||||
$ref: '#/components/schemas/QueryMatchResult'
|
||||
nullable: true
|
||||
type:
|
||||
$ref: '#/components/schemas/DataProviderType'
|
||||
nullable: true
|
||||
DataProviderResult:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -1157,41 +1108,59 @@ components:
|
|||
type: object
|
||||
properties:
|
||||
exists:
|
||||
type: boolean
|
||||
nullable: true
|
||||
type: string
|
||||
match_all:
|
||||
nullable: true
|
||||
type: string
|
||||
meta:
|
||||
nullable: true
|
||||
type: object
|
||||
properties:
|
||||
alias:
|
||||
nullable: true
|
||||
type: string
|
||||
controlledBy:
|
||||
nullable: true
|
||||
type: string
|
||||
disabled:
|
||||
nullable: true
|
||||
type: boolean
|
||||
field:
|
||||
nullable: true
|
||||
type: string
|
||||
formattedValue:
|
||||
nullable: true
|
||||
type: string
|
||||
index:
|
||||
nullable: true
|
||||
type: string
|
||||
key:
|
||||
nullable: true
|
||||
type: string
|
||||
negate:
|
||||
nullable: true
|
||||
type: boolean
|
||||
params:
|
||||
nullable: true
|
||||
type: string
|
||||
type:
|
||||
nullable: true
|
||||
type: string
|
||||
value:
|
||||
nullable: true
|
||||
type: string
|
||||
missing:
|
||||
nullable: true
|
||||
type: string
|
||||
query:
|
||||
nullable: true
|
||||
type: string
|
||||
range:
|
||||
nullable: true
|
||||
type: string
|
||||
script:
|
||||
nullable: true
|
||||
type: string
|
||||
GetNotesResult:
|
||||
type: object
|
||||
|
@ -1256,6 +1225,12 @@ components:
|
|||
version:
|
||||
nullable: true
|
||||
type: string
|
||||
required:
|
||||
- savedObjectId
|
||||
- version
|
||||
- pinnedEventIds
|
||||
- eventNotes
|
||||
- globalNotes
|
||||
Note:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/BareNote'
|
||||
|
@ -1275,6 +1250,23 @@ components:
|
|||
- $ref: '#/components/schemas/PinnedEventBaseResponseBody'
|
||||
- nullable: true
|
||||
type: object
|
||||
PersistTimelineResponse:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
persistTimeline:
|
||||
type: object
|
||||
properties:
|
||||
timeline:
|
||||
$ref: '#/components/schemas/TimelineResponse'
|
||||
required:
|
||||
- timeline
|
||||
required:
|
||||
- persistTimeline
|
||||
required:
|
||||
- data
|
||||
PinnedEvent:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/BarePinnedEvent'
|
||||
|
@ -1312,34 +1304,27 @@ components:
|
|||
nullable: true
|
||||
type: string
|
||||
value:
|
||||
nullable: true
|
||||
type: string
|
||||
Readable:
|
||||
oneOf:
|
||||
- nullable: true
|
||||
type: string
|
||||
- items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
ResolvedTimeline:
|
||||
type: object
|
||||
properties:
|
||||
_data:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
_encoding:
|
||||
alias_purpose:
|
||||
$ref: '#/components/schemas/SavedObjectResolveAliasPurpose'
|
||||
alias_target_id:
|
||||
type: string
|
||||
_events:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
_eventsCount:
|
||||
type: number
|
||||
_maxListeners:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
_position:
|
||||
type: number
|
||||
_read:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
_readableState:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
readable:
|
||||
type: boolean
|
||||
outcome:
|
||||
$ref: '#/components/schemas/SavedObjectResolveOutcome'
|
||||
timeline:
|
||||
$ref: '#/components/schemas/TimelineSavedToReturnObject'
|
||||
required:
|
||||
- timeline
|
||||
- outcome
|
||||
ResponseNote:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -1374,6 +1359,17 @@ components:
|
|||
- threat_match
|
||||
- zeek
|
||||
type: string
|
||||
SavedObjectResolveAliasPurpose:
|
||||
enum:
|
||||
- savedObjectConversion
|
||||
- savedObjectImport
|
||||
type: string
|
||||
SavedObjectResolveOutcome:
|
||||
enum:
|
||||
- exactMatch
|
||||
- aliasMatch
|
||||
- conflict
|
||||
type: string
|
||||
SavedTimeline:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -1402,12 +1398,16 @@ components:
|
|||
properties:
|
||||
end:
|
||||
oneOf:
|
||||
- type: string
|
||||
- type: number
|
||||
- nullable: true
|
||||
type: string
|
||||
- nullable: true
|
||||
type: number
|
||||
start:
|
||||
oneOf:
|
||||
- type: string
|
||||
- type: number
|
||||
- nullable: true
|
||||
type: string
|
||||
- nullable: true
|
||||
type: number
|
||||
description:
|
||||
nullable: true
|
||||
type: string
|
||||
|
@ -1496,6 +1496,18 @@ components:
|
|||
updatedBy:
|
||||
nullable: true
|
||||
type: string
|
||||
SavedTimelineWithSavedObjectId:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SavedTimeline'
|
||||
- type: object
|
||||
properties:
|
||||
savedObjectId:
|
||||
type: string
|
||||
version:
|
||||
type: string
|
||||
required:
|
||||
- savedObjectId
|
||||
- version
|
||||
SerializedFilterQueryResult:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -1545,27 +1557,63 @@ components:
|
|||
TimelineResponse:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SavedTimeline'
|
||||
- $ref: '#/components/schemas/SavedTimelineWithSavedObjectId'
|
||||
- type: object
|
||||
properties:
|
||||
eventIdToNoteIds:
|
||||
items:
|
||||
$ref: '#/components/schemas/Note'
|
||||
nullable: true
|
||||
type: array
|
||||
noteIds:
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
notes:
|
||||
items:
|
||||
$ref: '#/components/schemas/Note'
|
||||
nullable: true
|
||||
type: array
|
||||
pinnedEventIds:
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
pinnedEventsSaveObject:
|
||||
items:
|
||||
$ref: '#/components/schemas/PinnedEvent'
|
||||
nullable: true
|
||||
type: array
|
||||
TimelineSavedToReturnObject:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SavedTimeline'
|
||||
- type: object
|
||||
properties:
|
||||
eventIdToNoteIds:
|
||||
items:
|
||||
$ref: '#/components/schemas/Note'
|
||||
nullable: true
|
||||
type: array
|
||||
noteIds:
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
notes:
|
||||
items:
|
||||
$ref: '#/components/schemas/Note'
|
||||
nullable: true
|
||||
type: array
|
||||
pinnedEventIds:
|
||||
items:
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
pinnedEventsSaveObject:
|
||||
items:
|
||||
$ref: '#/components/schemas/PinnedEvent'
|
||||
nullable: true
|
||||
type: array
|
||||
savedObjectId:
|
||||
type: string
|
||||
|
|
|
@ -9,9 +9,10 @@ import { FilterStateStore } from '@kbn/es-query';
|
|||
|
||||
import type { DataTableModel } from '@kbn/securitysolution-data-table';
|
||||
import { VIEW_SELECTION } from '../../../common/constants';
|
||||
import type { TimelineResult } from '../../../common/api/timeline';
|
||||
import { TimelineId, TimelineTabs } from '../../../common/types/timeline';
|
||||
import type { TimelineResponse } from '../../../common/api/timeline';
|
||||
import {
|
||||
type ColumnHeaderResult,
|
||||
RowRendererIdEnum,
|
||||
TimelineTypeEnum,
|
||||
TimelineStatusEnum,
|
||||
|
@ -1986,9 +1987,11 @@ export const mockDataTableModel: DataTableModel = {
|
|||
},
|
||||
};
|
||||
|
||||
export const mockGetOneTimelineResult: TimelineResult = {
|
||||
export const mockGetOneTimelineResult: TimelineResponse = {
|
||||
savedObjectId: 'ef579e40-jibber-jabber',
|
||||
columns: timelineDefaults.columns.filter((column) => column.id !== 'event.action'),
|
||||
columns: timelineDefaults.columns.filter(
|
||||
(column) => column.id !== 'event.action'
|
||||
) as ColumnHeaderResult[],
|
||||
dateRange: { start: '2020-03-18T13:46:38.929Z', end: '2020-03-18T13:52:38.929Z' },
|
||||
description: 'This is a sample rule description',
|
||||
eventType: 'all',
|
||||
|
|
|
@ -50,8 +50,8 @@ import {
|
|||
isNewTermsRule,
|
||||
isThresholdRule,
|
||||
} from '../../../../common/detection_engine/utils';
|
||||
import type { TimelineResult } from '../../../../common/api/timeline';
|
||||
import { TimelineId } from '../../../../common/types/timeline';
|
||||
import type { TimelineResponse } from '../../../../common/api/timeline';
|
||||
import { TimelineStatusEnum, TimelineTypeEnum } from '../../../../common/api/timeline';
|
||||
import type {
|
||||
SendAlertToTimelineActionProps,
|
||||
|
@ -69,7 +69,7 @@ import { TimelineEventsQueries } from '../../../../common/search_strategy/timeli
|
|||
import { timelineDefaults } from '../../../timelines/store/defaults';
|
||||
import {
|
||||
omitTypenameInTimeline,
|
||||
formatTimelineResultToModel,
|
||||
formatTimelineResponseToModel,
|
||||
} from '../../../timelines/components/open_timeline/helpers';
|
||||
import { convertKueryToElasticSearchQuery } from '../../../common/lib/kuery';
|
||||
import { getField, getFieldKey } from '../../../helpers';
|
||||
|
@ -983,11 +983,15 @@ export const sendAlertToTimelineAction = async ({
|
|||
),
|
||||
]);
|
||||
|
||||
const resultingTimeline: TimelineResult = getOr({}, 'data.getOneTimeline', responseTimeline);
|
||||
const resultingTimeline: TimelineResponse = getOr(
|
||||
{},
|
||||
'data.getOneTimeline',
|
||||
responseTimeline
|
||||
);
|
||||
const eventData: TimelineEventsDetailsItem[] = eventDataResp.data ?? [];
|
||||
if (!isEmpty(resultingTimeline)) {
|
||||
const timelineTemplate: TimelineResult = omitTypenameInTimeline(resultingTimeline);
|
||||
const { timeline, notes } = formatTimelineResultToModel(
|
||||
const timelineTemplate = omitTypenameInTimeline(resultingTimeline);
|
||||
const { timeline, notes } = formatTimelineResponseToModel(
|
||||
timelineTemplate,
|
||||
true,
|
||||
timelineTemplate.timelineType ?? TimelineTypeEnum.default
|
||||
|
|
|
@ -20,12 +20,16 @@ import {
|
|||
isUntitled,
|
||||
omitTypenameInTimeline,
|
||||
useQueryTimelineById,
|
||||
formatTimelineResultToModel,
|
||||
formatTimelineResponseToModel,
|
||||
} from './helpers';
|
||||
import type { OpenTimelineResult } from './types';
|
||||
import { TimelineId } from '../../../../common/types/timeline';
|
||||
import type { RowRendererId } from '../../../../common/api/timeline';
|
||||
import { TimelineTypeEnum, TimelineStatusEnum } from '../../../../common/api/timeline';
|
||||
import {
|
||||
TimelineTypeEnum,
|
||||
TimelineStatusEnum,
|
||||
type ColumnHeaderResult,
|
||||
type RowRendererId,
|
||||
} from '../../../../common/api/timeline';
|
||||
import {
|
||||
mockTimeline as mockSelectedTimeline,
|
||||
mockTemplate as mockSelectedTemplate,
|
||||
|
@ -379,7 +383,7 @@ describe('helpers', () => {
|
|||
);
|
||||
const timeline = {
|
||||
savedObjectId: 'savedObject-1',
|
||||
columns: columnsWithoutEventAction,
|
||||
columns: columnsWithoutEventAction as ColumnHeaderResult[],
|
||||
version: '1',
|
||||
};
|
||||
|
||||
|
@ -396,7 +400,7 @@ describe('helpers', () => {
|
|||
);
|
||||
const timeline = {
|
||||
savedObjectId: 'savedObject-1',
|
||||
columns: columnsWithoutEventAction,
|
||||
columns: columnsWithoutEventAction as ColumnHeaderResult[],
|
||||
filters: [
|
||||
{
|
||||
meta: {
|
||||
|
@ -568,7 +572,7 @@ describe('helpers', () => {
|
|||
version: '1',
|
||||
status: TimelineStatusEnum.active,
|
||||
timelineType: TimelineTypeEnum.default,
|
||||
columns: customColumns,
|
||||
columns: customColumns as ColumnHeaderResult[],
|
||||
};
|
||||
|
||||
const newTimeline = defaultTimelineToTimelineModel(
|
||||
|
@ -691,7 +695,7 @@ describe('helpers', () => {
|
|||
});
|
||||
|
||||
test('Do not override daterange if TimelineStatus is active', () => {
|
||||
const { timeline } = formatTimelineResultToModel(
|
||||
const { timeline } = formatTimelineResponseToModel(
|
||||
omitTypenameInTimeline(getOr({}, 'data.timeline', selectedTimeline)),
|
||||
args.duplicate,
|
||||
args.timelineType
|
||||
|
@ -744,7 +748,7 @@ describe('helpers', () => {
|
|||
});
|
||||
|
||||
test('should not override daterange if TimelineStatus is active', () => {
|
||||
const { timeline } = formatTimelineResultToModel(
|
||||
const { timeline } = formatTimelineResponseToModel(
|
||||
omitTypenameInTimeline(getOr({}, 'data.timeline', selectedTimeline)),
|
||||
args.duplicate,
|
||||
args.timelineType
|
||||
|
@ -818,7 +822,7 @@ describe('helpers', () => {
|
|||
});
|
||||
|
||||
test('override daterange if TimelineStatus is immutable', () => {
|
||||
const { timeline } = formatTimelineResultToModel(
|
||||
const { timeline } = formatTimelineResponseToModel(
|
||||
omitTypenameInTimeline(getOr({}, 'data.timeline', template)),
|
||||
args.duplicate,
|
||||
args.timelineType
|
||||
|
|
|
@ -14,8 +14,8 @@ import { useCallback } from 'react';
|
|||
import { useDiscoverInTimelineContext } from '../../../common/components/discover_in_timeline/use_discover_in_timeline_context';
|
||||
import type { ColumnHeaderOptions } from '../../../../common/types/timeline';
|
||||
import type {
|
||||
TimelineResult,
|
||||
SingleTimelineResolveResponse,
|
||||
TimelineResponse,
|
||||
ResolvedTimeline,
|
||||
ColumnHeaderResult,
|
||||
FilterTimelineResult,
|
||||
DataProviderResult,
|
||||
|
@ -80,7 +80,7 @@ export const isUntitled = ({ title }: OpenTimelineResult): boolean =>
|
|||
const omitTypename = (key: string, value: keyof TimelineModel) =>
|
||||
key === '__typename' ? undefined : value;
|
||||
|
||||
export const omitTypenameInTimeline = (timeline: TimelineResult): TimelineResult =>
|
||||
export const omitTypenameInTimeline = (timeline: TimelineResponse): TimelineResponse =>
|
||||
JSON.parse(JSON.stringify(timeline), omitTypename);
|
||||
|
||||
const parseString = (params: string) => {
|
||||
|
@ -164,7 +164,7 @@ const setPinnedEventIds = (duplicate: boolean, pinnedEventIds: string[] | null |
|
|||
: {};
|
||||
|
||||
const getTemplateTimelineId = (
|
||||
timeline: TimelineResult,
|
||||
timeline: TimelineResponse,
|
||||
duplicate: boolean,
|
||||
targetTimelineType?: TimelineType
|
||||
) => {
|
||||
|
@ -200,7 +200,7 @@ const convertToDefaultField = ({ and, ...dataProvider }: DataProviderResult) =>
|
|||
|
||||
const getDataProviders = (
|
||||
duplicate: boolean,
|
||||
dataProviders: TimelineResult['dataProviders'],
|
||||
dataProviders: TimelineResponse['dataProviders'],
|
||||
timelineType?: TimelineType
|
||||
) => {
|
||||
if (duplicate && dataProviders && timelineType === TimelineTypeEnum.default) {
|
||||
|
@ -214,7 +214,7 @@ const getDataProviders = (
|
|||
};
|
||||
|
||||
export const getTimelineTitle = (
|
||||
timeline: TimelineResult,
|
||||
timeline: TimelineResponse,
|
||||
duplicate: boolean,
|
||||
timelineType?: TimelineType
|
||||
) => {
|
||||
|
@ -225,7 +225,7 @@ export const getTimelineTitle = (
|
|||
};
|
||||
|
||||
export const getTimelineStatus = (
|
||||
timeline: TimelineResult,
|
||||
timeline: TimelineResponse,
|
||||
duplicate: boolean,
|
||||
timelineType?: TimelineType
|
||||
) => {
|
||||
|
@ -236,7 +236,7 @@ export const getTimelineStatus = (
|
|||
};
|
||||
|
||||
export const defaultTimelineToTimelineModel = (
|
||||
timeline: TimelineResult,
|
||||
timeline: TimelineResponse,
|
||||
duplicate: boolean,
|
||||
timelineType?: TimelineType,
|
||||
unifiedComponentsInTimelineDisabled?: boolean
|
||||
|
@ -291,8 +291,8 @@ export const defaultTimelineToTimelineModel = (
|
|||
);
|
||||
};
|
||||
|
||||
export const formatTimelineResultToModel = (
|
||||
timelineToOpen: TimelineResult,
|
||||
export const formatTimelineResponseToModel = (
|
||||
timelineToOpen: TimelineResponse,
|
||||
duplicate: boolean = false,
|
||||
timelineType?: TimelineType,
|
||||
unifiedComponentsInTimelineDisabled?: boolean
|
||||
|
@ -376,12 +376,12 @@ export const useQueryTimelineById = () => {
|
|||
} else {
|
||||
return Promise.resolve(resolveTimeline(timelineId))
|
||||
.then((result) => {
|
||||
const data: SingleTimelineResolveResponse['data'] | null = getOr(null, 'data', result);
|
||||
const data: ResolvedTimeline | null = getOr(null, 'data', result);
|
||||
if (!data) return;
|
||||
|
||||
const timelineToOpen = omitTypenameInTimeline(data.timeline);
|
||||
|
||||
const { timeline, notes } = formatTimelineResultToModel(
|
||||
const { timeline, notes } = formatTimelineResponseToModel(
|
||||
timelineToOpen,
|
||||
duplicate,
|
||||
timelineType,
|
||||
|
|
|
@ -10,7 +10,7 @@ import type { IconType } from '@elastic/eui';
|
|||
import type { TimelineModel } from '../../store/model';
|
||||
import type {
|
||||
RowRendererId,
|
||||
SingleTimelineResolveResponse,
|
||||
ResolvedTimeline,
|
||||
TimelineType,
|
||||
TimelineStatus,
|
||||
TemplateTimelineType,
|
||||
|
@ -210,9 +210,9 @@ export interface OpenTimelineProps {
|
|||
}
|
||||
|
||||
export interface ResolveTimelineConfig {
|
||||
alias_target_id: SingleTimelineResolveResponse['data']['alias_target_id'];
|
||||
outcome: SingleTimelineResolveResponse['data']['outcome'];
|
||||
alias_purpose: SingleTimelineResolveResponse['data']['alias_purpose'];
|
||||
alias_target_id: ResolvedTimeline['alias_target_id'];
|
||||
outcome: ResolvedTimeline['outcome'];
|
||||
alias_purpose: ResolvedTimeline['alias_purpose'];
|
||||
}
|
||||
export interface UpdateTimeline {
|
||||
duplicate: boolean;
|
||||
|
|
|
@ -21,9 +21,9 @@ import type {
|
|||
TimelineType,
|
||||
TimelineStatus,
|
||||
PageInfoTimeline,
|
||||
TimelineResult,
|
||||
TimelineResponse,
|
||||
SortTimeline,
|
||||
GetAllTimelineVariables,
|
||||
GetTimelinesRequestQuery,
|
||||
} from '../../../../common/api/timeline';
|
||||
import { TimelineTypeEnum } from '../../../../common/api/timeline';
|
||||
import { getAllTimelines } from '../api';
|
||||
|
@ -59,7 +59,7 @@ export interface AllTimelinesVariables {
|
|||
export const ALL_TIMELINE_QUERY_ID = 'FETCH_ALL_TIMELINES';
|
||||
|
||||
export const getAllTimeline = memoizeOne(
|
||||
(_variables: string, timelines: TimelineResult[]): OpenTimelineResult[] =>
|
||||
(_variables: string, timelines: TimelineResponse[]): OpenTimelineResult[] =>
|
||||
timelines.map((timeline) => ({
|
||||
created: timeline.created,
|
||||
description: timeline.description,
|
||||
|
@ -132,13 +132,15 @@ export const useGetAllTimeline = (): AllTimelinesArgs => {
|
|||
loading: true,
|
||||
}));
|
||||
|
||||
const variables: GetAllTimelineVariables = {
|
||||
onlyUserFavorite,
|
||||
pageInfo,
|
||||
const variables: GetTimelinesRequestQuery = {
|
||||
only_user_favorite: onlyUserFavorite ? 'true' : 'false',
|
||||
page_size: pageInfo.pageSize.toString(),
|
||||
page_index: pageInfo.pageIndex.toString(),
|
||||
search,
|
||||
sort,
|
||||
status,
|
||||
timelineType,
|
||||
sort_field: sort.sortField,
|
||||
sort_order: sort.sortOrder,
|
||||
status: status || undefined,
|
||||
timeline_type: timelineType,
|
||||
};
|
||||
const getAllTimelineResponse = await getAllTimelines(variables, abortCtrl.signal);
|
||||
const totalCount = getAllTimelineResponse?.totalCount ?? 0;
|
||||
|
@ -163,7 +165,7 @@ export const useGetAllTimeline = (): AllTimelinesArgs => {
|
|||
setAllTimelines({
|
||||
loading: false,
|
||||
totalCount,
|
||||
timelines: getAllTimeline(JSON.stringify(variables), timelines as TimelineResult[]),
|
||||
timelines: getAllTimeline(JSON.stringify(variables), timelines as TimelineResponse[]),
|
||||
customTemplateTimelineCount,
|
||||
defaultTimelineCount,
|
||||
elasticTemplateTimelineCount,
|
||||
|
|
|
@ -5,34 +5,30 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { fold } from 'fp-ts/lib/Either';
|
||||
import { identity } from 'fp-ts/lib/function';
|
||||
import { pipe } from 'fp-ts/lib/pipeable';
|
||||
import { isEmpty } from 'lodash';
|
||||
|
||||
import { throwErrors } from '@kbn/cases-plugin/common';
|
||||
import type { SavedSearch } from '@kbn/saved-search-plugin/common';
|
||||
|
||||
import type {
|
||||
TimelineResponse,
|
||||
TimelineErrorResponse,
|
||||
ImportTimelineResultSchema,
|
||||
AllTimelinesResponse,
|
||||
SingleTimelineResponse,
|
||||
SingleTimelineResolveResponse,
|
||||
GetTimelinesArgs,
|
||||
CleanDraftTimelinesResponse,
|
||||
TimelineType,
|
||||
PatchTimelineResponse,
|
||||
CreateTimelinesResponse,
|
||||
CopyTimelineResponse,
|
||||
GetDraftTimelinesResponse,
|
||||
GetTimelinesRequestQuery,
|
||||
SavedTimeline,
|
||||
} from '../../../common/api/timeline';
|
||||
import {
|
||||
TimelineResponseType,
|
||||
ImportTimelineResult,
|
||||
TimelineErrorResponse,
|
||||
TimelineStatusEnum,
|
||||
TimelineErrorResponseType,
|
||||
importTimelineResultSchema,
|
||||
allTimelinesResponse,
|
||||
PersistFavoriteRouteResponse,
|
||||
SingleTimelineResponseType,
|
||||
type TimelineType,
|
||||
TimelineTypeEnum,
|
||||
ResolvedSingleTimelineResponseType,
|
||||
GetTimelineResponse,
|
||||
ResolveTimelineResponse,
|
||||
GetTimelinesResponse,
|
||||
PersistTimelineResponse,
|
||||
} from '../../../common/api/timeline';
|
||||
import {
|
||||
TIMELINE_URL,
|
||||
|
@ -48,15 +44,15 @@ import {
|
|||
|
||||
import { KibanaServices } from '../../common/lib/kibana';
|
||||
import { ToasterError } from '../../common/components/toasters';
|
||||
import { parseOrThrowErrorFactory } from '../../../common/timelines/zod_errors';
|
||||
import type {
|
||||
ExportDocumentsProps,
|
||||
ImportDataProps,
|
||||
ImportDataResponse,
|
||||
} from '../../detection_engine/rule_management/logic';
|
||||
import type { TimelineInput } from '../../../common/search_strategy';
|
||||
|
||||
interface RequestPostTimeline {
|
||||
timeline: TimelineInput;
|
||||
timeline: SavedTimeline;
|
||||
signal?: AbortSignal;
|
||||
}
|
||||
|
||||
|
@ -68,48 +64,33 @@ interface RequestPatchTimeline<T = string> extends RequestPostTimeline {
|
|||
|
||||
type RequestPersistTimeline = RequestPostTimeline & Partial<RequestPatchTimeline<null | string>>;
|
||||
const createToasterPlainError = (message: string) => new ToasterError([message]);
|
||||
const decodeTimelineResponse = (respTimeline?: TimelineResponse | TimelineErrorResponse) =>
|
||||
pipe(
|
||||
TimelineResponseType.decode(respTimeline),
|
||||
fold(throwErrors(createToasterPlainError), identity)
|
||||
);
|
||||
|
||||
const decodeSingleTimelineResponse = (respTimeline?: SingleTimelineResponse) =>
|
||||
pipe(
|
||||
SingleTimelineResponseType.decode(respTimeline),
|
||||
fold(throwErrors(createToasterPlainError), identity)
|
||||
);
|
||||
const parseOrThrow = parseOrThrowErrorFactory(createToasterPlainError);
|
||||
|
||||
const decodeResolvedSingleTimelineResponse = (respTimeline?: SingleTimelineResolveResponse) =>
|
||||
pipe(
|
||||
ResolvedSingleTimelineResponseType.decode(respTimeline),
|
||||
fold(throwErrors(createToasterPlainError), identity)
|
||||
);
|
||||
const decodeTimelineResponse = (respTimeline?: PersistTimelineResponse | TimelineErrorResponse) =>
|
||||
parseOrThrow(PersistTimelineResponse)(respTimeline);
|
||||
|
||||
const decodeAllTimelinesResponse = (respTimeline: AllTimelinesResponse) =>
|
||||
pipe(
|
||||
allTimelinesResponse.decode(respTimeline),
|
||||
fold(throwErrors(createToasterPlainError), identity)
|
||||
);
|
||||
const decodeSingleTimelineResponse = (respTimeline?: GetTimelineResponse) =>
|
||||
parseOrThrow(GetTimelineResponse)(respTimeline);
|
||||
|
||||
const decodeResolvedSingleTimelineResponse = (respTimeline?: ResolveTimelineResponse) =>
|
||||
parseOrThrow(ResolveTimelineResponse)(respTimeline);
|
||||
|
||||
const decodeGetTimelinesResponse = (respTimeline: GetTimelinesResponse) =>
|
||||
parseOrThrow(GetTimelinesResponse)(respTimeline);
|
||||
|
||||
const decodeTimelineErrorResponse = (respTimeline?: TimelineErrorResponse) =>
|
||||
pipe(
|
||||
TimelineErrorResponseType.decode(respTimeline),
|
||||
fold(throwErrors(createToasterPlainError), identity)
|
||||
);
|
||||
parseOrThrow(TimelineErrorResponse)(respTimeline);
|
||||
|
||||
const decodePrepackedTimelineResponse = (respTimeline?: ImportTimelineResultSchema) =>
|
||||
pipe(
|
||||
importTimelineResultSchema.decode(respTimeline),
|
||||
fold(throwErrors(createToasterPlainError), identity)
|
||||
);
|
||||
const decodePrepackedTimelineResponse = (respTimeline?: ImportTimelineResult) =>
|
||||
parseOrThrow(ImportTimelineResult)(respTimeline);
|
||||
|
||||
const decodeResponseFavoriteTimeline = (respTimeline?: PersistFavoriteRouteResponse) =>
|
||||
PersistFavoriteRouteResponse.parse(respTimeline);
|
||||
parseOrThrow(PersistFavoriteRouteResponse)(respTimeline);
|
||||
|
||||
const postTimeline = async ({
|
||||
timeline,
|
||||
}: RequestPostTimeline): Promise<TimelineResponse | TimelineErrorResponse> => {
|
||||
}: RequestPostTimeline): Promise<CreateTimelinesResponse | TimelineErrorResponse> => {
|
||||
let requestBody;
|
||||
try {
|
||||
requestBody = JSON.stringify({ timeline });
|
||||
|
@ -117,7 +98,7 @@ const postTimeline = async ({
|
|||
return Promise.reject(new Error(`Failed to stringify query: ${JSON.stringify(err)}`));
|
||||
}
|
||||
|
||||
const response = await KibanaServices.get().http.post<TimelineResponse>(TIMELINE_URL, {
|
||||
const response = await KibanaServices.get().http.post<CreateTimelinesResponse>(TIMELINE_URL, {
|
||||
method: 'POST',
|
||||
body: requestBody,
|
||||
version: '2023-10-31',
|
||||
|
@ -131,7 +112,7 @@ const patchTimeline = async ({
|
|||
timeline,
|
||||
version,
|
||||
savedSearch,
|
||||
}: RequestPatchTimeline): Promise<TimelineResponse | TimelineErrorResponse> => {
|
||||
}: RequestPatchTimeline): Promise<PatchTimelineResponse | TimelineErrorResponse> => {
|
||||
let response = null;
|
||||
let requestBody = null;
|
||||
try {
|
||||
|
@ -153,7 +134,7 @@ const patchTimeline = async ({
|
|||
}
|
||||
|
||||
try {
|
||||
response = await KibanaServices.get().http.patch<TimelineResponse>(TIMELINE_URL, {
|
||||
response = await KibanaServices.get().http.patch<PatchTimelineResponse>(TIMELINE_URL, {
|
||||
method: 'PATCH',
|
||||
body: requestBody,
|
||||
version: '2023-10-31',
|
||||
|
@ -175,7 +156,7 @@ export const copyTimeline = async ({
|
|||
timelineId,
|
||||
timeline,
|
||||
savedSearch,
|
||||
}: RequestPersistTimeline): Promise<TimelineResponse | TimelineErrorResponse> => {
|
||||
}: RequestPersistTimeline): Promise<CopyTimelineResponse | TimelineErrorResponse> => {
|
||||
let response = null;
|
||||
let requestBody = null;
|
||||
let newSavedSearchId = null;
|
||||
|
@ -205,7 +186,7 @@ export const copyTimeline = async ({
|
|||
}
|
||||
|
||||
try {
|
||||
response = await KibanaServices.get().http.post<TimelineResponse>(TIMELINE_COPY_URL, {
|
||||
response = await KibanaServices.get().http.post<CopyTimelineResponse>(TIMELINE_COPY_URL, {
|
||||
method: 'POST',
|
||||
body: requestBody,
|
||||
version: '1',
|
||||
|
@ -224,10 +205,10 @@ export const persistTimeline = async ({
|
|||
timeline,
|
||||
version,
|
||||
savedSearch,
|
||||
}: RequestPersistTimeline): Promise<TimelineResponse | TimelineErrorResponse> => {
|
||||
}: RequestPersistTimeline): Promise<PersistTimelineResponse | TimelineErrorResponse> => {
|
||||
try {
|
||||
if (isEmpty(timelineId) && timeline.status === TimelineStatusEnum.draft && timeline) {
|
||||
const temp: TimelineResponse | TimelineErrorResponse = await cleanDraftTimeline({
|
||||
const temp: CleanDraftTimelinesResponse | TimelineErrorResponse = await cleanDraftTimeline({
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
timelineType: timeline.timelineType!,
|
||||
templateTimelineId: timeline.templateTimelineId ?? undefined,
|
||||
|
@ -330,13 +311,16 @@ export const getDraftTimeline = async ({
|
|||
timelineType,
|
||||
}: {
|
||||
timelineType: TimelineType;
|
||||
}): Promise<TimelineResponse> => {
|
||||
const response = await KibanaServices.get().http.get<TimelineResponse>(TIMELINE_DRAFT_URL, {
|
||||
query: {
|
||||
timelineType,
|
||||
},
|
||||
version: '2023-10-31',
|
||||
});
|
||||
}): Promise<GetDraftTimelinesResponse> => {
|
||||
const response = await KibanaServices.get().http.get<GetDraftTimelinesResponse>(
|
||||
TIMELINE_DRAFT_URL,
|
||||
{
|
||||
query: {
|
||||
timelineType,
|
||||
},
|
||||
version: '2023-10-31',
|
||||
}
|
||||
);
|
||||
|
||||
return decodeTimelineResponse(response);
|
||||
};
|
||||
|
@ -349,7 +333,7 @@ export const cleanDraftTimeline = async ({
|
|||
timelineType: TimelineType;
|
||||
templateTimelineId?: string;
|
||||
templateTimelineVersion?: number;
|
||||
}): Promise<TimelineResponse | TimelineErrorResponse> => {
|
||||
}): Promise<CleanDraftTimelinesResponse | TimelineErrorResponse> => {
|
||||
let requestBody;
|
||||
const templateTimelineInfo =
|
||||
timelineType === TimelineTypeEnum.template
|
||||
|
@ -366,16 +350,19 @@ export const cleanDraftTimeline = async ({
|
|||
} catch (err) {
|
||||
return Promise.reject(new Error(`Failed to stringify query: ${JSON.stringify(err)}`));
|
||||
}
|
||||
const response = await KibanaServices.get().http.post<TimelineResponse>(TIMELINE_DRAFT_URL, {
|
||||
body: requestBody,
|
||||
version: '2023-10-31',
|
||||
});
|
||||
const response = await KibanaServices.get().http.post<CleanDraftTimelinesResponse>(
|
||||
TIMELINE_DRAFT_URL,
|
||||
{
|
||||
body: requestBody,
|
||||
version: '2023-10-31',
|
||||
}
|
||||
);
|
||||
|
||||
return decodeTimelineResponse(response);
|
||||
};
|
||||
|
||||
export const installPrepackedTimelines = async (): Promise<ImportTimelineResultSchema> => {
|
||||
const response = await KibanaServices.get().http.post<ImportTimelineResultSchema>(
|
||||
export const installPrepackedTimelines = async (): Promise<ImportTimelineResult> => {
|
||||
const response = await KibanaServices.get().http.post<ImportTimelineResult>(
|
||||
TIMELINE_PREPACKAGED_URL,
|
||||
{
|
||||
version: '2023-10-31',
|
||||
|
@ -386,7 +373,7 @@ export const installPrepackedTimelines = async (): Promise<ImportTimelineResultS
|
|||
};
|
||||
|
||||
export const getTimeline = async (id: string) => {
|
||||
const response = await KibanaServices.get().http.get<SingleTimelineResponse>(TIMELINE_URL, {
|
||||
const response = await KibanaServices.get().http.get<GetTimelineResponse>(TIMELINE_URL, {
|
||||
query: {
|
||||
id,
|
||||
},
|
||||
|
@ -397,7 +384,7 @@ export const getTimeline = async (id: string) => {
|
|||
};
|
||||
|
||||
export const resolveTimeline = async (id: string) => {
|
||||
const response = await KibanaServices.get().http.get<SingleTimelineResolveResponse>(
|
||||
const response = await KibanaServices.get().http.get<ResolveTimelineResponse>(
|
||||
TIMELINE_RESOLVE_URL,
|
||||
{
|
||||
query: {
|
||||
|
@ -411,7 +398,7 @@ export const resolveTimeline = async (id: string) => {
|
|||
};
|
||||
|
||||
export const getTimelineTemplate = async (templateTimelineId: string) => {
|
||||
const response = await KibanaServices.get().http.get<SingleTimelineResponse>(TIMELINE_URL, {
|
||||
const response = await KibanaServices.get().http.get<GetTimelineResponse>(TIMELINE_URL, {
|
||||
query: {
|
||||
template_timeline_id: templateTimelineId,
|
||||
},
|
||||
|
@ -421,24 +408,18 @@ export const getTimelineTemplate = async (templateTimelineId: string) => {
|
|||
return decodeSingleTimelineResponse(response);
|
||||
};
|
||||
|
||||
export const getAllTimelines = async (args: GetTimelinesArgs, abortSignal: AbortSignal) => {
|
||||
const response = await KibanaServices.get().http.fetch<AllTimelinesResponse>(TIMELINES_URL, {
|
||||
export const getAllTimelines = async (
|
||||
query: GetTimelinesRequestQuery,
|
||||
abortSignal: AbortSignal
|
||||
) => {
|
||||
const response = await KibanaServices.get().http.fetch<GetTimelinesResponse>(TIMELINES_URL, {
|
||||
method: 'GET',
|
||||
query: {
|
||||
...(args.onlyUserFavorite ? { only_user_favorite: args.onlyUserFavorite } : {}),
|
||||
...(args?.pageInfo?.pageSize ? { page_size: args.pageInfo.pageSize } : {}),
|
||||
...(args?.pageInfo?.pageIndex ? { page_index: args.pageInfo.pageIndex } : {}),
|
||||
...(args.search ? { search: args.search } : {}),
|
||||
...(args?.sort?.sortField ? { sort_field: args?.sort?.sortField } : {}),
|
||||
...(args?.sort?.sortOrder ? { sort_order: args?.sort?.sortOrder } : {}),
|
||||
...(args.status ? { status: args.status } : {}),
|
||||
...(args.timelineType ? { timeline_type: args.timelineType } : {}),
|
||||
},
|
||||
query,
|
||||
signal: abortSignal,
|
||||
version: '2023-10-31',
|
||||
});
|
||||
|
||||
return decodeAllTimelinesResponse(response);
|
||||
return decodeGetTimelinesResponse(response);
|
||||
};
|
||||
|
||||
export const persistFavorite = async ({
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
*/
|
||||
|
||||
import { TableId } from '@kbn/securitysolution-data-table';
|
||||
import type { TimelineResult } from '../../../common/api/timeline';
|
||||
import type { TimelineResponse } from '../../../common/api/timeline';
|
||||
import { DEFAULT_ALERTS_INDEX } from '../../../common/constants';
|
||||
|
||||
export const getTimelineQueryTypes = (timeline: TimelineResult) => ({
|
||||
export const getTimelineQueryTypes = (timeline: TimelineResponse) => ({
|
||||
hasQuery:
|
||||
(timeline.kqlQuery != null &&
|
||||
timeline.kqlQuery.filterQuery != null &&
|
||||
|
|
|
@ -66,6 +66,7 @@ describe('Timeline pinned event middleware', () => {
|
|||
data: {
|
||||
persistPinnedEventOnTimeline: {
|
||||
code: 200,
|
||||
eventId: testEventId,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -74,7 +74,7 @@ export const addPinnedEventToTimelineMiddleware: (kibana: CoreStart) => Middlewa
|
|||
const currentTimeline = selectTimelineById(store.getState(), action.payload.id);
|
||||
// The response is null or empty in case we unpinned an event.
|
||||
// In that case we want to remove the locally pinned event.
|
||||
if (!response || !('code' in response)) {
|
||||
if (!response || !('eventId' in response)) {
|
||||
return store.dispatch(
|
||||
updateTimeline({
|
||||
id: action.payload.id,
|
||||
|
|
|
@ -167,7 +167,7 @@ describe('Timeline save middleware', () => {
|
|||
});
|
||||
|
||||
it('should show an error message when the call is unauthorized', async () => {
|
||||
(persistTimeline as jest.Mock).mockResolvedValue({ data: { persistTimeline: { code: 403 } } });
|
||||
(persistTimeline as jest.Mock).mockResolvedValue({ status_code: 403 });
|
||||
await store.dispatch(saveTimeline({ id: TimelineId.test, saveAsNew: false }));
|
||||
|
||||
expect(refreshTimelines as unknown as jest.Mock).not.toHaveBeenCalled();
|
||||
|
@ -175,7 +175,7 @@ describe('Timeline save middleware', () => {
|
|||
});
|
||||
|
||||
describe('#convertTimelineAsInput ', () => {
|
||||
test('should return a TimelineInput instead of TimelineModel ', () => {
|
||||
test('should return a SavedTimeline instead of TimelineModel ', () => {
|
||||
const columns: TimelineModel['columns'] = [
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
|
|
|
@ -34,8 +34,11 @@ import { selectTimelineById } from '../selectors';
|
|||
import * as i18n from '../../pages/translations';
|
||||
import type { inputsModel } from '../../../common/store/inputs';
|
||||
import { TimelineStatusEnum, TimelineTypeEnum } from '../../../../common/api/timeline';
|
||||
import type { TimelineErrorResponse, TimelineResponse } from '../../../../common/api/timeline';
|
||||
import type { TimelineInput } from '../../../../common/search_strategy';
|
||||
import type {
|
||||
TimelineErrorResponse,
|
||||
PersistTimelineResponse,
|
||||
SavedTimeline,
|
||||
} from '../../../../common/api/timeline';
|
||||
import type { TimelineModel } from '../model';
|
||||
import type { ColumnHeaderOptions } from '../../../../common/types/timeline';
|
||||
import { refreshTimelines } from './helpers';
|
||||
|
@ -83,6 +86,9 @@ export const saveTimelineMiddleware: (kibana: CoreStart) => Middleware<{}, State
|
|||
if (isTimelineErrorResponse(result)) {
|
||||
const error = getErrorFromResponse(result);
|
||||
switch (error?.errorCode) {
|
||||
case 403:
|
||||
store.dispatch(showCallOutUnauthorizedMsg());
|
||||
break;
|
||||
// conflict
|
||||
case 409:
|
||||
kibana.notifications.toasts.addDanger({
|
||||
|
@ -108,11 +114,6 @@ export const saveTimelineMiddleware: (kibana: CoreStart) => Middleware<{}, State
|
|||
return;
|
||||
}
|
||||
|
||||
if (response && response.code === 403) {
|
||||
store.dispatch(showCallOutUnauthorizedMsg());
|
||||
return;
|
||||
}
|
||||
|
||||
refreshTimelines(store.getState());
|
||||
|
||||
store.dispatch(
|
||||
|
@ -155,7 +156,7 @@ export const saveTimelineMiddleware: (kibana: CoreStart) => Middleware<{}, State
|
|||
return ret;
|
||||
};
|
||||
|
||||
const timelineInput: TimelineInput = {
|
||||
const timelineInput: SavedTimeline = {
|
||||
columns: null,
|
||||
dataProviders: null,
|
||||
dataViewId: null,
|
||||
|
@ -181,8 +182,8 @@ const timelineInput: TimelineInput = {
|
|||
export const convertTimelineAsInput = (
|
||||
timeline: TimelineModel,
|
||||
timelineTimeRange: inputsModel.TimeRange
|
||||
): TimelineInput =>
|
||||
Object.keys(timelineInput).reduce<TimelineInput>((acc, key) => {
|
||||
): SavedTimeline =>
|
||||
Object.keys(timelineInput).reduce<SavedTimeline>((acc, key) => {
|
||||
if (has(key, timeline)) {
|
||||
if (key === 'kqlQuery') {
|
||||
return set(`${key}.filterQuery`, get(`${key}.filterQuery`, timeline), acc);
|
||||
|
@ -270,7 +271,7 @@ const convertToString = (obj: unknown) => {
|
|||
}
|
||||
};
|
||||
|
||||
type PossibleResponse = TimelineResponse | TimelineErrorResponse;
|
||||
type PossibleResponse = PersistTimelineResponse | TimelineErrorResponse;
|
||||
|
||||
function isTimelineErrorResponse(response: PossibleResponse): response is TimelineErrorResponse {
|
||||
return response && ('status_code' in response || 'statusCode' in response);
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
*/
|
||||
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import { validate } from '@kbn/securitysolution-io-ts-utils';
|
||||
import { checkTimelineStatusRt } from '../../../../../../common/api/timeline';
|
||||
import { InstallPrepackedTimelinesRequestBody } from '../../../../../../common/api/timeline';
|
||||
import { buildSiemResponse } from '../../../routes/utils';
|
||||
import type { SecuritySolutionPluginRouter } from '../../../../../types';
|
||||
|
||||
|
@ -69,10 +68,8 @@ export const getPrebuiltRulesAndTimelinesStatusRoute = (router: SecuritySolution
|
|||
|
||||
const frameworkRequest = await buildFrameworkRequest(context, request);
|
||||
const prebuiltTimelineStatus = await checkTimelinesStatus(frameworkRequest);
|
||||
const [validatedPrebuiltTimelineStatus] = validate(
|
||||
prebuiltTimelineStatus,
|
||||
checkTimelineStatusRt
|
||||
);
|
||||
const validatedPrebuiltTimelineStatus =
|
||||
InstallPrepackedTimelinesRequestBody.parse(prebuiltTimelineStatus);
|
||||
|
||||
const responseBody: ReadPrebuiltRulesAndTimelinesStatusResponse = {
|
||||
rules_custom_installed: customRules.total,
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { validate } from '@kbn/securitysolution-io-ts-utils';
|
||||
import { importTimelineResultSchema } from '../../../../../common/api/timeline';
|
||||
import { stringifyZodError } from '@kbn/zod-helpers';
|
||||
import { ImportTimelineResult } from '../../../../../common/api/timeline';
|
||||
import type { SecuritySolutionApiRequestHandlerContext } from '../../../../types';
|
||||
import { installPrepackagedTimelines } from '../../../timeline/routes/prepackaged_timelines/install_prepackaged_timelines';
|
||||
|
||||
|
@ -18,10 +18,10 @@ export const performTimelinesInstallation = async (
|
|||
securitySolutionContext.getFrameworkRequest(),
|
||||
true
|
||||
);
|
||||
const [result, error] = validate(timeline, importTimelineResultSchema);
|
||||
const parsed = ImportTimelineResult.safeParse(timeline);
|
||||
|
||||
return {
|
||||
result,
|
||||
error,
|
||||
result: parsed.data,
|
||||
error: parsed.error && stringifyZodError(parsed.error),
|
||||
};
|
||||
};
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
|
||||
import path, { join, resolve } from 'path';
|
||||
import type * as rt from 'io-ts';
|
||||
|
||||
import {
|
||||
TIMELINE_DRAFT_URL,
|
||||
|
@ -17,9 +16,9 @@ import {
|
|||
} from '../../../../common/constants';
|
||||
import type {
|
||||
SavedTimeline,
|
||||
patchTimelineSchema,
|
||||
createTimelineSchema,
|
||||
GetTimelineQuery,
|
||||
PatchTimelineRequestBody,
|
||||
CreateTimelinesRequestBody,
|
||||
GetTimelineRequestQuery,
|
||||
} from '../../../../common/api/timeline';
|
||||
import {
|
||||
type TimelineType,
|
||||
|
@ -135,14 +134,14 @@ export const updateTemplateTimelineWithTimelineId = {
|
|||
version: 'WzEyMjUsMV0=',
|
||||
};
|
||||
|
||||
export const getCreateTimelinesRequest = (mockBody: rt.TypeOf<typeof createTimelineSchema>) =>
|
||||
export const getCreateTimelinesRequest = (mockBody: CreateTimelinesRequestBody) =>
|
||||
requestMock.create({
|
||||
method: 'post',
|
||||
path: TIMELINE_URL,
|
||||
body: mockBody,
|
||||
});
|
||||
|
||||
export const getUpdateTimelinesRequest = (mockBody: rt.TypeOf<typeof patchTimelineSchema>) =>
|
||||
export const getUpdateTimelinesRequest = (mockBody: PatchTimelineRequestBody) =>
|
||||
requestMock.create({
|
||||
method: 'patch',
|
||||
path: TIMELINE_URL,
|
||||
|
@ -167,7 +166,7 @@ export const cleanDraftTimelinesRequest = (timelineType: TimelineType) =>
|
|||
},
|
||||
});
|
||||
|
||||
export const getTimelineRequest = (query?: GetTimelineQuery) =>
|
||||
export const getTimelineRequest = (query?: GetTimelineRequestQuery) =>
|
||||
requestMock.create({
|
||||
method: 'get',
|
||||
path: TIMELINE_URL,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { ResolvedTimelineWithOutcomeSavedObject } from '../../../../common/api/timeline';
|
||||
import type { ResolvedTimeline } from '../../../../common/api/timeline';
|
||||
import { TimelineStatusEnum, TimelineTypeEnum } from '../../../../common/api/timeline';
|
||||
|
||||
export const mockResolvedSavedObject = {
|
||||
|
@ -117,7 +117,7 @@ export const mockPopulatedTimeline = {
|
|||
pinnedEventsSaveObject: [],
|
||||
};
|
||||
|
||||
export const mockResolveTimelineResponse: ResolvedTimelineWithOutcomeSavedObject = {
|
||||
export const mockResolveTimelineResponse: ResolvedTimeline = {
|
||||
timeline: mockPopulatedTimeline,
|
||||
outcome: 'aliasMatch',
|
||||
alias_target_id: 'new-saved-object-id',
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
*/
|
||||
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import type { IKibanaResponse } from '@kbn/core-http-server';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
import type { SecuritySolutionPluginRouter } from '../../../../../types';
|
||||
import type { ConfigType } from '../../../../..';
|
||||
import { buildSiemResponse } from '../../../../detection_engine/routes/utils';
|
||||
|
||||
import { TIMELINE_DRAFT_URL } from '../../../../../../common/constants';
|
||||
|
@ -21,12 +21,13 @@ import {
|
|||
persistTimeline,
|
||||
} from '../../../saved_object/timelines';
|
||||
import { draftTimelineDefaults } from '../../../utils/default_timeline';
|
||||
import type { CleanDraftTimelinesResponse } from '../../../../../../common/api/timeline';
|
||||
import {
|
||||
CleanDraftTimelinesRequestBody,
|
||||
TimelineTypeEnum,
|
||||
} from '../../../../../../common/api/timeline';
|
||||
|
||||
export const cleanDraftTimelinesRoute = (router: SecuritySolutionPluginRouter, _: ConfigType) => {
|
||||
export const cleanDraftTimelinesRoute = (router: SecuritySolutionPluginRouter) => {
|
||||
router.versioned
|
||||
.post({
|
||||
path: TIMELINE_DRAFT_URL,
|
||||
|
@ -42,7 +43,7 @@ export const cleanDraftTimelinesRoute = (router: SecuritySolutionPluginRouter, _
|
|||
},
|
||||
version: '2023-10-31',
|
||||
},
|
||||
async (context, request, response) => {
|
||||
async (context, request, response): Promise<IKibanaResponse<CleanDraftTimelinesResponse>> => {
|
||||
const frameworkRequest = await buildFrameworkRequest(context, request);
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
|
|
|
@ -5,19 +5,22 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { IKibanaResponse } from '@kbn/core-http-server';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
import type { SecuritySolutionPluginRouter } from '../../../../../types';
|
||||
import type { ConfigType } from '../../../../..';
|
||||
import { buildSiemResponse } from '../../../../detection_engine/routes/utils';
|
||||
|
||||
import { TIMELINE_DRAFT_URL } from '../../../../../../common/constants';
|
||||
import { buildFrameworkRequest } from '../../../utils/common';
|
||||
import { buildRouteValidationWithExcess } from '../../../../../utils/build_validation/route_validation';
|
||||
import { getDraftTimeline, persistTimeline } from '../../../saved_object/timelines';
|
||||
import { draftTimelineDefaults } from '../../../utils/default_timeline';
|
||||
import { getDraftTimelineSchema } from '../../../../../../common/api/timeline';
|
||||
import {
|
||||
GetDraftTimelinesRequestQuery,
|
||||
type GetDraftTimelinesResponse,
|
||||
} from '../../../../../../common/api/timeline';
|
||||
|
||||
export const getDraftTimelinesRoute = (router: SecuritySolutionPluginRouter, _: ConfigType) => {
|
||||
export const getDraftTimelinesRoute = (router: SecuritySolutionPluginRouter) => {
|
||||
router.versioned
|
||||
.get({
|
||||
path: TIMELINE_DRAFT_URL,
|
||||
|
@ -29,11 +32,11 @@ export const getDraftTimelinesRoute = (router: SecuritySolutionPluginRouter, _:
|
|||
.addVersion(
|
||||
{
|
||||
validate: {
|
||||
request: { query: buildRouteValidationWithExcess(getDraftTimelineSchema) },
|
||||
request: { query: buildRouteValidationWithZod(GetDraftTimelinesRequestQuery) },
|
||||
},
|
||||
version: '2023-10-31',
|
||||
},
|
||||
async (context, request, response) => {
|
||||
async (context, request, response): Promise<IKibanaResponse<GetDraftTimelinesResponse>> => {
|
||||
const frameworkRequest = await buildFrameworkRequest(context, request);
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
|
|
|
@ -28,25 +28,25 @@ import { persistNoteRoute, deleteNoteRoute, getNotesRoute } from './notes';
|
|||
import { persistPinnedEventRoute } from './pinned_events';
|
||||
|
||||
export function registerTimelineRoutes(router: SecuritySolutionPluginRouter, config: ConfigType) {
|
||||
createTimelinesRoute(router, config);
|
||||
patchTimelinesRoute(router, config);
|
||||
createTimelinesRoute(router);
|
||||
patchTimelinesRoute(router);
|
||||
|
||||
importTimelinesRoute(router, config);
|
||||
exportTimelinesRoute(router, config);
|
||||
getDraftTimelinesRoute(router, config);
|
||||
getTimelineRoute(router, config);
|
||||
resolveTimelineRoute(router, config);
|
||||
getTimelinesRoute(router, config);
|
||||
cleanDraftTimelinesRoute(router, config);
|
||||
deleteTimelinesRoute(router, config);
|
||||
persistFavoriteRoute(router, config);
|
||||
copyTimelineRoute(router, config);
|
||||
getDraftTimelinesRoute(router);
|
||||
getTimelineRoute(router);
|
||||
resolveTimelineRoute(router);
|
||||
getTimelinesRoute(router);
|
||||
cleanDraftTimelinesRoute(router);
|
||||
deleteTimelinesRoute(router);
|
||||
persistFavoriteRoute(router);
|
||||
copyTimelineRoute(router);
|
||||
|
||||
installPrepackedTimelinesRoute(router, config);
|
||||
|
||||
persistNoteRoute(router, config);
|
||||
deleteNoteRoute(router, config);
|
||||
getNotesRoute(router, config);
|
||||
persistNoteRoute(router);
|
||||
deleteNoteRoute(router);
|
||||
getNotesRoute(router);
|
||||
|
||||
persistPinnedEventRoute(router, config);
|
||||
persistPinnedEventRoute(router);
|
||||
}
|
||||
|
|
|
@ -5,21 +5,20 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { IKibanaResponse } from '@kbn/core-http-server';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
import type { SecuritySolutionPluginRouter } from '../../../../types';
|
||||
|
||||
import { NOTE_URL } from '../../../../../common/constants';
|
||||
|
||||
import type { ConfigType } from '../../../..';
|
||||
|
||||
import { buildSiemResponse } from '../../../detection_engine/routes/utils';
|
||||
|
||||
import { buildFrameworkRequest } from '../../utils/common';
|
||||
import { DeleteNoteRequestBody, type DeleteNoteResponse } from '../../../../../common/api/timeline';
|
||||
import { deleteNote } from '../../saved_object/notes';
|
||||
|
||||
export const deleteNoteRoute = (router: SecuritySolutionPluginRouter, config: ConfigType) => {
|
||||
export const deleteNoteRoute = (router: SecuritySolutionPluginRouter) => {
|
||||
router.versioned
|
||||
.delete({
|
||||
path: NOTE_URL,
|
||||
|
@ -35,7 +34,7 @@ export const deleteNoteRoute = (router: SecuritySolutionPluginRouter, config: Co
|
|||
},
|
||||
version: '2023-10-31',
|
||||
},
|
||||
async (context, request, response) => {
|
||||
async (context, request, response): Promise<IKibanaResponse<DeleteNoteResponse>> => {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
try {
|
||||
|
@ -55,9 +54,8 @@ export const deleteNoteRoute = (router: SecuritySolutionPluginRouter, config: Co
|
|||
noteIds,
|
||||
});
|
||||
|
||||
const body: DeleteNoteResponse = { data: {} };
|
||||
return response.ok({
|
||||
body,
|
||||
body: { data: {} },
|
||||
});
|
||||
} catch (err) {
|
||||
const error = transformError(err);
|
||||
|
|
|
@ -5,21 +5,20 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { IKibanaResponse } from '@kbn/core-http-server';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import type { SortOrder } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
import type { SecuritySolutionPluginRouter } from '../../../../types';
|
||||
import { NOTE_URL } from '../../../../../common/constants';
|
||||
|
||||
import type { ConfigType } from '../../../..';
|
||||
|
||||
import { buildSiemResponse } from '../../../detection_engine/routes/utils';
|
||||
import { buildFrameworkRequest } from '../../utils/common';
|
||||
import { getAllSavedNote, MAX_UNASSOCIATED_NOTES } from '../../saved_object/notes';
|
||||
import { noteSavedObjectType } from '../../saved_object_mappings/notes';
|
||||
import { GetNotesRequestQuery, type GetNotesResponse } from '../../../../../common/api/timeline';
|
||||
|
||||
export const getNotesRoute = (router: SecuritySolutionPluginRouter, _: ConfigType) => {
|
||||
export const getNotesRoute = (router: SecuritySolutionPluginRouter) => {
|
||||
router.versioned
|
||||
.get({
|
||||
path: NOTE_URL,
|
||||
|
@ -35,7 +34,7 @@ export const getNotesRoute = (router: SecuritySolutionPluginRouter, _: ConfigTyp
|
|||
},
|
||||
version: '2023-10-31',
|
||||
},
|
||||
async (context, request, response) => {
|
||||
async (context, request, response): Promise<IKibanaResponse<GetNotesResponse>> => {
|
||||
try {
|
||||
const queryParams = request.query;
|
||||
const frameworkRequest = await buildFrameworkRequest(context, request);
|
||||
|
@ -60,8 +59,7 @@ export const getNotesRoute = (router: SecuritySolutionPluginRouter, _: ConfigTyp
|
|||
perPage: MAX_UNASSOCIATED_NOTES,
|
||||
};
|
||||
const res = await getAllSavedNote(frameworkRequest, options);
|
||||
const body: GetNotesResponse = res ?? {};
|
||||
return response.ok({ body });
|
||||
return response.ok({ body: res ?? {} });
|
||||
}
|
||||
} else {
|
||||
const perPage = queryParams?.perPage ? parseInt(queryParams.perPage, 10) : 10;
|
||||
|
|
|
@ -5,14 +5,13 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { IKibanaResponse } from '@kbn/core-http-server';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
import type { SecuritySolutionPluginRouter } from '../../../../types';
|
||||
|
||||
import { NOTE_URL } from '../../../../../common/constants';
|
||||
|
||||
import type { ConfigType } from '../../../..';
|
||||
|
||||
import { buildSiemResponse } from '../../../detection_engine/routes/utils';
|
||||
|
||||
import { buildFrameworkRequest } from '../../utils/common';
|
||||
|
@ -22,7 +21,7 @@ import {
|
|||
} from '../../../../../common/api/timeline';
|
||||
import { persistNote } from '../../saved_object/notes';
|
||||
|
||||
export const persistNoteRoute = (router: SecuritySolutionPluginRouter, _: ConfigType) => {
|
||||
export const persistNoteRoute = (router: SecuritySolutionPluginRouter) => {
|
||||
router.versioned
|
||||
.patch({
|
||||
path: NOTE_URL,
|
||||
|
@ -38,7 +37,7 @@ export const persistNoteRoute = (router: SecuritySolutionPluginRouter, _: Config
|
|||
},
|
||||
version: '2023-10-31',
|
||||
},
|
||||
async (context, request, response) => {
|
||||
async (context, request, response): Promise<IKibanaResponse<PersistNoteRouteResponse>> => {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
try {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { IKibanaResponse } from '@kbn/core-http-server';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
|
||||
|
@ -12,8 +13,6 @@ import type { SecuritySolutionPluginRouter } from '../../../../types';
|
|||
|
||||
import { PINNED_EVENT_URL } from '../../../../../common/constants';
|
||||
|
||||
import type { ConfigType } from '../../../..';
|
||||
|
||||
import { buildSiemResponse } from '../../../detection_engine/routes/utils';
|
||||
|
||||
import { buildFrameworkRequest } from '../../utils/common';
|
||||
|
@ -23,10 +22,7 @@ import {
|
|||
} from '../../../../../common/api/timeline';
|
||||
import { persistPinnedEventOnTimeline } from '../../saved_object/pinned_events';
|
||||
|
||||
export const persistPinnedEventRoute = (
|
||||
router: SecuritySolutionPluginRouter,
|
||||
config: ConfigType
|
||||
) => {
|
||||
export const persistPinnedEventRoute = (router: SecuritySolutionPluginRouter) => {
|
||||
router.versioned
|
||||
.patch({
|
||||
path: PINNED_EVENT_URL,
|
||||
|
@ -42,7 +38,11 @@ export const persistPinnedEventRoute = (
|
|||
},
|
||||
version: '2023-10-31',
|
||||
},
|
||||
async (context, request, response) => {
|
||||
async (
|
||||
context,
|
||||
request,
|
||||
response
|
||||
): Promise<IKibanaResponse<PersistPinnedEventRouteResponse>> => {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
try {
|
||||
|
@ -58,12 +58,10 @@ export const persistPinnedEventRoute = (
|
|||
timelineId
|
||||
);
|
||||
|
||||
const body: PersistPinnedEventRouteResponse = {
|
||||
data: { persistPinnedEventOnTimeline: res },
|
||||
};
|
||||
|
||||
return response.ok({
|
||||
body,
|
||||
body: {
|
||||
data: { persistPinnedEventOnTimeline: res },
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
const error = transformError(err);
|
||||
|
|
|
@ -20,7 +20,6 @@ import {
|
|||
import * as helpers from './helpers';
|
||||
import { importTimelines } from '../../timelines/import_timelines/helpers';
|
||||
import { buildFrameworkRequest } from '../../../utils/common';
|
||||
import type { ImportTimelineResultSchema } from '../../../../../../common/api/timeline';
|
||||
|
||||
jest.mock('../../timelines/import_timelines/helpers');
|
||||
|
||||
|
@ -231,9 +230,8 @@ describe('installPrepackagedTimelines', () => {
|
|||
);
|
||||
|
||||
expect(
|
||||
(result as ImportTimelineResultSchema).errors[0].error.message.includes(
|
||||
'read prepackaged timelines error:'
|
||||
)
|
||||
'errors' in result &&
|
||||
result.errors?.[0].error?.message?.includes('read prepackaged timelines error:')
|
||||
).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import path, { join, resolve } from 'path';
|
||||
import { Readable } from 'stream';
|
||||
|
||||
import type { ImportTimelineResultSchema } from '../../../../../../common/api/timeline';
|
||||
import type { ImportTimelineResult } from '../../../../../../common/api/timeline';
|
||||
|
||||
import type { FrameworkRequest } from '../../../../framework';
|
||||
|
||||
|
@ -22,7 +22,7 @@ export const installPrepackagedTimelines = async (
|
|||
isImmutable: boolean,
|
||||
filePath?: string,
|
||||
fileName?: string
|
||||
): Promise<ImportTimelineResultSchema | Error> => {
|
||||
): Promise<ImportTimelineResult | Error> => {
|
||||
let readStream;
|
||||
const dir = resolve(
|
||||
join(
|
||||
|
@ -47,7 +47,7 @@ export const installPrepackagedTimelines = async (
|
|||
],
|
||||
};
|
||||
}
|
||||
return loadData<null, ImportTimelineResultSchema>(readStream, <T>(docs: T) =>
|
||||
return loadData<null, ImportTimelineResult>(readStream, <T>(docs: T) =>
|
||||
docs instanceof Readable
|
||||
? importTimelines(docs, maxTimelineImportExportSize, frameworkRequest, isImmutable)
|
||||
: Promise.reject(new Error(`read prepackaged timelines error`))
|
||||
|
|
|
@ -6,14 +6,17 @@
|
|||
*/
|
||||
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import { validate } from '@kbn/securitysolution-io-ts-utils';
|
||||
import { checkTimelineStatusRt } from '../../../../../../common/api/timeline';
|
||||
import type { IKibanaResponse } from '@kbn/core-http-server';
|
||||
|
||||
import type { SecuritySolutionPluginRouter } from '../../../../../types';
|
||||
|
||||
import { TIMELINE_PREPACKAGED_URL } from '../../../../../../common/constants';
|
||||
|
||||
import type { ConfigType } from '../../../../../config';
|
||||
|
||||
import {
|
||||
InstallPrepackedTimelinesRequestBody,
|
||||
type InstallPrepackedTimelinesResponse,
|
||||
} from '../../../../../../common/api/timeline';
|
||||
import { buildSiemResponse } from '../../../../detection_engine/routes/utils';
|
||||
|
||||
import { installPrepackagedTimelines } from './helpers';
|
||||
|
@ -45,23 +48,24 @@ export const installPrepackedTimelinesRoute = (
|
|||
validate: {},
|
||||
version: '2023-10-31',
|
||||
},
|
||||
async (context, request, response) => {
|
||||
async (
|
||||
context,
|
||||
request,
|
||||
response
|
||||
): Promise<IKibanaResponse<InstallPrepackedTimelinesResponse>> => {
|
||||
try {
|
||||
const frameworkRequest = await buildFrameworkRequest(context, request);
|
||||
const prepackagedTimelineStatus = await checkTimelinesStatus(frameworkRequest);
|
||||
const [validatedprepackagedTimelineStatus, prepackagedTimelineStatusError] = validate(
|
||||
prepackagedTimelineStatus,
|
||||
checkTimelineStatusRt
|
||||
);
|
||||
|
||||
if (prepackagedTimelineStatusError != null) {
|
||||
throw prepackagedTimelineStatusError;
|
||||
const installResult =
|
||||
InstallPrepackedTimelinesRequestBody.safeParse(prepackagedTimelineStatus);
|
||||
|
||||
if (installResult.error) {
|
||||
throw installResult.error;
|
||||
}
|
||||
|
||||
const timelinesToInstalled =
|
||||
validatedprepackagedTimelineStatus?.timelinesToInstall.length ?? 0;
|
||||
const timelinesNotUpdated =
|
||||
validatedprepackagedTimelineStatus?.timelinesToUpdate.length ?? 0;
|
||||
const timelinesToInstalled = installResult.data.timelinesToInstall.length ?? 0;
|
||||
const timelinesNotUpdated = installResult.data.timelinesToUpdate.length ?? 0;
|
||||
let res = null;
|
||||
|
||||
if (timelinesToInstalled > 0 || timelinesNotUpdated > 0) {
|
||||
|
|
|
@ -5,10 +5,13 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { IKibanaResponse } from '@kbn/core-http-server';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import { buildRouteValidationWithExcess } from '../../../../../utils/build_validation/route_validation';
|
||||
import type { ConfigType } from '../../../../..';
|
||||
import { copyTimelineSchema } from '../../../../../../common/api/timeline';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
import {
|
||||
CopyTimelineRequestBody,
|
||||
type CopyTimelineResponse,
|
||||
} from '../../../../../../common/api/timeline';
|
||||
import { copyTimeline } from '../../../saved_object/timelines';
|
||||
import type { SecuritySolutionPluginRouter } from '../../../../../types';
|
||||
import { TIMELINE_COPY_URL } from '../../../../../../common/constants';
|
||||
|
@ -16,7 +19,7 @@ import { buildSiemResponse } from '../../../../detection_engine/routes/utils';
|
|||
|
||||
import { buildFrameworkRequest } from '../../../utils/common';
|
||||
|
||||
export const copyTimelineRoute = (router: SecuritySolutionPluginRouter, _: ConfigType) => {
|
||||
export const copyTimelineRoute = (router: SecuritySolutionPluginRouter) => {
|
||||
router.versioned
|
||||
.post({
|
||||
path: TIMELINE_COPY_URL,
|
||||
|
@ -29,17 +32,16 @@ export const copyTimelineRoute = (router: SecuritySolutionPluginRouter, _: Confi
|
|||
{
|
||||
version: '1',
|
||||
validate: {
|
||||
request: { body: buildRouteValidationWithExcess(copyTimelineSchema) },
|
||||
request: { body: buildRouteValidationWithZod(CopyTimelineRequestBody) },
|
||||
},
|
||||
},
|
||||
async (context, request, response) => {
|
||||
async (context, request, response): Promise<IKibanaResponse<CopyTimelineResponse>> => {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
try {
|
||||
const frameworkRequest = await buildFrameworkRequest(context, request);
|
||||
const { timeline, timelineIdToCopy } = request.body;
|
||||
const copiedTimeline = await copyTimeline(frameworkRequest, timeline, timelineIdToCopy);
|
||||
|
||||
return response.ok({
|
||||
body: { data: { persistTimeline: copiedTimeline } },
|
||||
});
|
||||
|
|
|
@ -10,8 +10,9 @@ import { isEmpty } from 'lodash/fp';
|
|||
import moment from 'moment';
|
||||
import { timeline as timelineLib, pinnedEvent as pinnedEventLib } from '../../../saved_object';
|
||||
import type { FrameworkRequest } from '../../../../framework';
|
||||
import type { ResponseTimeline, SavedTimeline, Note } from '../../../../../../common/api/timeline';
|
||||
import type { SavedTimeline, Note } from '../../../../../../common/api/timeline';
|
||||
import { persistNotes } from '../../../saved_object/notes/persist_notes';
|
||||
import type { InternalTimelineResponse } from '../../../saved_object/timelines';
|
||||
|
||||
interface CreateTimelineProps {
|
||||
frameworkRequest: FrameworkRequest;
|
||||
|
@ -21,7 +22,7 @@ interface CreateTimelineProps {
|
|||
overrideNotesOwner?: boolean;
|
||||
pinnedEventIds?: string[] | null;
|
||||
notes?: Note[];
|
||||
existingNoteIds?: string[];
|
||||
existingNoteIds?: string[] | null;
|
||||
isImmutable?: boolean;
|
||||
}
|
||||
|
||||
|
@ -40,7 +41,7 @@ export const createTimelines = async ({
|
|||
existingNoteIds = [],
|
||||
isImmutable,
|
||||
overrideNotesOwner = true,
|
||||
}: CreateTimelineProps): Promise<ResponseTimeline> => {
|
||||
}: CreateTimelineProps): Promise<InternalTimelineResponse> => {
|
||||
const timerangeStart = isImmutable
|
||||
? moment().subtract(24, 'hours').toISOString()
|
||||
: timeline.dateRange?.start;
|
||||
|
|
|
@ -7,16 +7,13 @@
|
|||
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import type { IKibanaResponse } from '@kbn/core/server';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
import type { SecuritySolutionPluginRouter } from '../../../../../types';
|
||||
|
||||
import { TIMELINE_URL } from '../../../../../../common/constants';
|
||||
|
||||
import type { ConfigType } from '../../../../..';
|
||||
import { buildRouteValidationWithExcess } from '../../../../../utils/build_validation/route_validation';
|
||||
|
||||
import { buildSiemResponse } from '../../../../detection_engine/routes/utils';
|
||||
|
||||
import { createTimelineSchema } from '../../../../../../common/api/timeline';
|
||||
import {
|
||||
buildFrameworkRequest,
|
||||
CompareTimelinesStatus,
|
||||
|
@ -24,11 +21,14 @@ import {
|
|||
} from '../../../utils/common';
|
||||
import { DEFAULT_ERROR } from '../../../utils/failure_cases';
|
||||
import { createTimelines } from './helpers';
|
||||
import type { CreateTimelinesResponse } from '../../../../../../common/api/timeline';
|
||||
import {
|
||||
CreateTimelinesRequestBody,
|
||||
type CreateTimelinesResponse,
|
||||
} from '../../../../../../common/api/timeline';
|
||||
|
||||
export * from './helpers';
|
||||
|
||||
export const createTimelinesRoute = (router: SecuritySolutionPluginRouter, _: ConfigType) => {
|
||||
export const createTimelinesRoute = (router: SecuritySolutionPluginRouter) => {
|
||||
router.versioned
|
||||
.post({
|
||||
path: TIMELINE_URL,
|
||||
|
@ -42,7 +42,7 @@ export const createTimelinesRoute = (router: SecuritySolutionPluginRouter, _: Co
|
|||
version: '2023-10-31',
|
||||
validate: {
|
||||
request: {
|
||||
body: buildRouteValidationWithExcess(createTimelineSchema),
|
||||
body: buildRouteValidationWithZod(CreateTimelinesRequestBody),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { IKibanaResponse } from '@kbn/core-http-server';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
import type { ConfigType } from '../../../../..';
|
||||
import {
|
||||
DeleteTimelinesRequestBody,
|
||||
type DeleteTimelinesResponse,
|
||||
|
@ -19,7 +19,7 @@ import { buildSiemResponse } from '../../../../detection_engine/routes/utils';
|
|||
import { buildFrameworkRequest } from '../../../utils/common';
|
||||
import { deleteTimeline } from '../../../saved_object/timelines';
|
||||
|
||||
export const deleteTimelinesRoute = (router: SecuritySolutionPluginRouter, config: ConfigType) => {
|
||||
export const deleteTimelinesRoute = (router: SecuritySolutionPluginRouter) => {
|
||||
router.versioned
|
||||
.delete({
|
||||
path: TIMELINE_URL,
|
||||
|
@ -35,7 +35,7 @@ export const deleteTimelinesRoute = (router: SecuritySolutionPluginRouter, confi
|
|||
request: { body: buildRouteValidationWithZod(DeleteTimelinesRequestBody) },
|
||||
},
|
||||
},
|
||||
async (context, request, response) => {
|
||||
async (context, request, response): Promise<IKibanaResponse<DeleteTimelinesResponse>> => {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
try {
|
||||
|
|
|
@ -9,11 +9,11 @@ import { omit } from 'lodash/fp';
|
|||
import { transformDataToNdjson } from '@kbn/securitysolution-utils';
|
||||
|
||||
import type {
|
||||
ExportedTimelines,
|
||||
ExportedNotes,
|
||||
ExportTimelineNotFoundError,
|
||||
Note,
|
||||
PinnedEvent,
|
||||
TimelineResponse,
|
||||
} from '../../../../../../common/api/timeline';
|
||||
|
||||
import type { FrameworkRequest } from '../../../../framework';
|
||||
|
@ -45,7 +45,7 @@ const getPinnedEventsIdsByTimelineId = (currentPinnedEvents: PinnedEvent[]): str
|
|||
const getTimelinesFromObjects = async (
|
||||
request: FrameworkRequest,
|
||||
ids?: string[] | null
|
||||
): Promise<Array<ExportedTimelines | ExportTimelineNotFoundError>> => {
|
||||
): Promise<Array<TimelineResponse | ExportTimelineNotFoundError>> => {
|
||||
const { timelines, errors } = await getSelectedTimelines(request, ids);
|
||||
const exportedIds = timelines.map((t) => t.savedObjectId);
|
||||
|
||||
|
@ -65,7 +65,7 @@ const getTimelinesFromObjects = async (
|
|||
[]
|
||||
);
|
||||
|
||||
const myResponse = exportedIds.reduce<ExportedTimelines[]>((acc, timelineId) => {
|
||||
const myResponse = exportedIds.reduce<TimelineResponse[]>((acc, timelineId) => {
|
||||
const myTimeline = timelines.find((t) => t.savedObjectId === timelineId);
|
||||
if (myTimeline != null) {
|
||||
const timelineNotes = myNotes.filter((n) => n.timelineId === timelineId);
|
||||
|
|
|
@ -5,11 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
serverMock,
|
||||
requestContextMock,
|
||||
createMockConfig,
|
||||
} from '../../../../detection_engine/routes/__mocks__';
|
||||
import { serverMock, requestContextMock } from '../../../../detection_engine/routes/__mocks__';
|
||||
import { getTimelineOrNull, getTimelineTemplateOrNull } from '../../../saved_object/timelines';
|
||||
|
||||
import { getTimelineRequest } from '../../../__mocks__/request_responses';
|
||||
|
@ -33,7 +29,7 @@ describe('get timeline', () => {
|
|||
server = serverMock.create();
|
||||
context = requestContextMock.createTools().context;
|
||||
|
||||
getTimelineRoute(server.router, createMockConfig());
|
||||
getTimelineRoute(server.router);
|
||||
});
|
||||
|
||||
test('should call getTimelineTemplateOrNull if templateTimelineId is given', async () => {
|
||||
|
|
|
@ -5,25 +5,24 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
import type { IKibanaResponse } from '@kbn/core-http-server';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import type { SecuritySolutionPluginRouter } from '../../../../../types';
|
||||
|
||||
import { TIMELINE_URL } from '../../../../../../common/constants';
|
||||
|
||||
import type { ConfigType } from '../../../../..';
|
||||
import { buildRouteValidationWithExcess } from '../../../../../utils/build_validation/route_validation';
|
||||
|
||||
import { buildSiemResponse } from '../../../../detection_engine/routes/utils';
|
||||
|
||||
import { buildFrameworkRequest } from '../../../utils/common';
|
||||
import { getTimelineQuerySchema } from '../../../../../../common/api/timeline';
|
||||
import { getTimelineTemplateOrNull, getTimelineOrNull } from '../../../saved_object/timelines';
|
||||
import type {
|
||||
TimelineSavedObject,
|
||||
ResolvedTimelineWithOutcomeSavedObject,
|
||||
import {
|
||||
GetTimelineRequestQuery,
|
||||
type GetTimelineResponse,
|
||||
} from '../../../../../../common/api/timeline';
|
||||
import { getTimelineTemplateOrNull, getTimelineOrNull } from '../../../saved_object/timelines';
|
||||
import type { ResolvedTimeline, TimelineResponse } from '../../../../../../common/api/timeline';
|
||||
|
||||
export const getTimelineRoute = (router: SecuritySolutionPluginRouter, _: ConfigType) => {
|
||||
export const getTimelineRoute = (router: SecuritySolutionPluginRouter) => {
|
||||
router.versioned
|
||||
.get({
|
||||
path: TIMELINE_URL,
|
||||
|
@ -36,16 +35,16 @@ export const getTimelineRoute = (router: SecuritySolutionPluginRouter, _: Config
|
|||
{
|
||||
version: '2023-10-31',
|
||||
validate: {
|
||||
request: { query: buildRouteValidationWithExcess(getTimelineQuerySchema) },
|
||||
request: { query: buildRouteValidationWithZod(GetTimelineRequestQuery) },
|
||||
},
|
||||
},
|
||||
async (context, request, response) => {
|
||||
async (context, request, response): Promise<IKibanaResponse<GetTimelineResponse>> => {
|
||||
try {
|
||||
const frameworkRequest = await buildFrameworkRequest(context, request);
|
||||
const query = request.query ?? {};
|
||||
const { template_timeline_id: templateTimelineId, id } = query;
|
||||
|
||||
let res: TimelineSavedObject | ResolvedTimelineWithOutcomeSavedObject | null = null;
|
||||
let res: TimelineResponse | ResolvedTimeline | null = null;
|
||||
|
||||
if (templateTimelineId != null && id == null) {
|
||||
res = await getTimelineTemplateOrNull(frameworkRequest, templateTimelineId);
|
||||
|
|
|
@ -5,11 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
serverMock,
|
||||
requestContextMock,
|
||||
createMockConfig,
|
||||
} from '../../../../detection_engine/routes/__mocks__';
|
||||
import { serverMock, requestContextMock } from '../../../../detection_engine/routes/__mocks__';
|
||||
import { getAllTimeline } from '../../../saved_object/timelines';
|
||||
import { getTimelineRequest } from '../../../__mocks__/request_responses';
|
||||
import { getTimelinesRoute } from '.';
|
||||
|
@ -29,7 +25,7 @@ describe('get all timelines', () => {
|
|||
server = serverMock.create();
|
||||
context = requestContextMock.createTools().context;
|
||||
|
||||
getTimelinesRoute(server.router, createMockConfig());
|
||||
getTimelinesRoute(server.router);
|
||||
});
|
||||
|
||||
test('should get the total count', async () => {
|
||||
|
|
|
@ -5,24 +5,23 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { pipe } from 'fp-ts/lib/pipeable';
|
||||
import { fold } from 'fp-ts/lib/Either';
|
||||
import { identity } from 'fp-ts/lib/function';
|
||||
import type { IKibanaResponse } from '@kbn/core-http-server';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import type { SecuritySolutionPluginRouter } from '../../../../../types';
|
||||
import { TIMELINES_URL } from '../../../../../../common/constants';
|
||||
|
||||
import type { ConfigType } from '../../../../..';
|
||||
|
||||
import { buildSiemResponse } from '../../../../detection_engine/routes/utils';
|
||||
|
||||
import { CustomHttpRequestError } from '../../../../../utils/custom_http_request_error';
|
||||
import { buildFrameworkRequest, escapeHatch, throwErrors } from '../../../utils/common';
|
||||
import { buildFrameworkRequest } from '../../../utils/common';
|
||||
import { getAllTimeline } from '../../../saved_object/timelines';
|
||||
import { getTimelinesQuerySchema } from '../../../../../../common/api/timeline';
|
||||
import {
|
||||
GetTimelinesRequestQuery,
|
||||
type GetTimelinesResponse,
|
||||
} from '../../../../../../common/api/timeline';
|
||||
|
||||
export const getTimelinesRoute = (router: SecuritySolutionPluginRouter, _: ConfigType) => {
|
||||
export const getTimelinesRoute = (router: SecuritySolutionPluginRouter) => {
|
||||
router.versioned
|
||||
.get({
|
||||
path: TIMELINES_URL,
|
||||
|
@ -34,27 +33,23 @@ export const getTimelinesRoute = (router: SecuritySolutionPluginRouter, _: Confi
|
|||
.addVersion(
|
||||
{
|
||||
validate: {
|
||||
request: { query: escapeHatch },
|
||||
request: { query: buildRouteValidationWithZod(GetTimelinesRequestQuery) },
|
||||
},
|
||||
version: '2023-10-31',
|
||||
},
|
||||
async (context, request, response) => {
|
||||
const customHttpRequestError = (message: string) =>
|
||||
new CustomHttpRequestError(message, 400);
|
||||
async (context, request, response): Promise<IKibanaResponse<GetTimelinesResponse>> => {
|
||||
try {
|
||||
const frameworkRequest = await buildFrameworkRequest(context, request);
|
||||
const queryParams = pipe(
|
||||
getTimelinesQuerySchema.decode(request.query),
|
||||
fold(throwErrors(customHttpRequestError), identity)
|
||||
);
|
||||
const onlyUserFavorite = queryParams?.only_user_favorite === 'true' ? true : false;
|
||||
const pageSize = queryParams?.page_size ? parseInt(queryParams.page_size, 10) : null;
|
||||
const pageIndex = queryParams?.page_index ? parseInt(queryParams.page_index, 10) : null;
|
||||
const search = queryParams?.search ?? null;
|
||||
const sortField = queryParams?.sort_field ?? null;
|
||||
const sortOrder = queryParams?.sort_order ?? null;
|
||||
const status = queryParams?.status ?? null;
|
||||
const timelineType = queryParams?.timeline_type ?? null;
|
||||
const onlyUserFavorite = request.query?.only_user_favorite === 'true';
|
||||
const pageSize = request.query?.page_size ? parseInt(request.query.page_size, 10) : null;
|
||||
const pageIndex = request.query?.page_index
|
||||
? parseInt(request.query.page_index, 10)
|
||||
: null;
|
||||
const search = request.query?.search ?? null;
|
||||
const sortField = request.query?.sort_field ?? null;
|
||||
const sortOrder = request.query?.sort_order ?? null;
|
||||
const status = request.query?.status ?? null;
|
||||
const timelineType = request.query?.timeline_type ?? null;
|
||||
const sort =
|
||||
sortField && sortOrder
|
||||
? {
|
||||
|
|
|
@ -5,11 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type * as rt from 'io-ts';
|
||||
import type { Transform } from 'stream';
|
||||
import { pipe } from 'fp-ts/lib/pipeable';
|
||||
import { fold } from 'fp-ts/lib/Either';
|
||||
import { identity } from 'fp-ts/lib/function';
|
||||
import { createConcatStream, createSplitStream, createMapStream } from '@kbn/utils';
|
||||
import { BadRequestError } from '@kbn/securitysolution-es-utils';
|
||||
import {
|
||||
|
@ -19,23 +15,15 @@ import {
|
|||
} from '../../../../../utils/read_stream/create_stream_from_ndjson';
|
||||
|
||||
import type { ImportTimelineResponse } from './types';
|
||||
import { ImportTimelinesSchemaRt } from '../../../../../../common/api/timeline';
|
||||
import { throwErrors } from '../../../utils/common';
|
||||
import { ImportTimelines } from '../../../../../../common/api/timeline';
|
||||
import { parseOrThrowErrorFactory } from '../../../../../../common/timelines/zod_errors';
|
||||
|
||||
type ErrorFactory = (message: string) => Error;
|
||||
const createPlainError = (message: string) => new Error(message);
|
||||
const parseOrThrow = parseOrThrowErrorFactory(createPlainError);
|
||||
|
||||
export const createPlainError = (message: string) => new Error(message);
|
||||
|
||||
export const decodeOrThrow =
|
||||
<A, O, I>(runtimeType: rt.Type<A, O, I>, createError: ErrorFactory = createPlainError) =>
|
||||
(inputValue: I) =>
|
||||
pipe(runtimeType.decode(inputValue), fold(throwErrors(createError), identity));
|
||||
|
||||
export const validateTimelines = (): Transform =>
|
||||
const validateTimelines = (): Transform =>
|
||||
createMapStream((obj: ImportTimelineResponse) =>
|
||||
obj instanceof Error
|
||||
? new BadRequestError(obj.message)
|
||||
: decodeOrThrow(ImportTimelinesSchemaRt)(obj)
|
||||
obj instanceof Error ? new BadRequestError(obj.message) : parseOrThrow(ImportTimelines)(obj)
|
||||
);
|
||||
export const createTimelinesStreamFromNdJson = (ruleLimit: number) => {
|
||||
return [
|
||||
|
|
|
@ -10,12 +10,8 @@ import type { Readable } from 'stream';
|
|||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { createPromiseFromStreams } from '@kbn/utils';
|
||||
|
||||
import { validate } from '@kbn/securitysolution-io-ts-utils';
|
||||
import type { ImportTimelineResultSchema } from '../../../../../../common/api/timeline';
|
||||
import {
|
||||
importTimelineResultSchema,
|
||||
TimelineStatusEnum,
|
||||
} from '../../../../../../common/api/timeline';
|
||||
import { stringifyZodError } from '@kbn/zod-helpers';
|
||||
import { ImportTimelineResult, TimelineStatusEnum } from '../../../../../../common/api/timeline';
|
||||
|
||||
import type { BulkError } from '../../../../detection_engine/routes/utils';
|
||||
import { createBulkErrorObject } from '../../../../detection_engine/routes/utils';
|
||||
|
@ -88,7 +84,7 @@ export const importTimelines = async (
|
|||
maxTimelineImportExportSize: number,
|
||||
frameworkRequest: FrameworkRequest,
|
||||
isImmutable?: boolean
|
||||
): Promise<ImportTimelineResultSchema | Error> => {
|
||||
): Promise<ImportTimelineResult | Error> => {
|
||||
const readStream = createTimelinesStreamFromNdJson(maxTimelineImportExportSize);
|
||||
|
||||
const parsedObjects = await createPromiseFromStreams<PromiseFromStreams[]>([file, ...readStream]);
|
||||
|
@ -262,17 +258,17 @@ export const importTimelines = async (
|
|||
const timelinesUpdated = importTimelineResponse.filter(
|
||||
(resp) => isImportRegular(resp) && resp.action === 'updateViaImport'
|
||||
);
|
||||
const importTimelinesRes: ImportTimelineResultSchema = {
|
||||
const importTimelinesRes: ImportTimelineResult = {
|
||||
success: errorsResp.length === 0,
|
||||
success_count: successes.length,
|
||||
errors: errorsResp,
|
||||
timelines_installed: timelinesInstalled.length ?? 0,
|
||||
timelines_updated: timelinesUpdated.length ?? 0,
|
||||
};
|
||||
const [validated, errors] = validate(importTimelinesRes, importTimelineResultSchema);
|
||||
if (errors != null || validated == null) {
|
||||
return new Error(errors || 'Import timeline error');
|
||||
const parseResult = ImportTimelineResult.safeParse(importTimelinesRes);
|
||||
if (parseResult.success && parseResult.data) {
|
||||
return parseResult.data;
|
||||
} else {
|
||||
return validated;
|
||||
return new Error(stringifyZodError(parseResult.error) || 'Import timeline error');
|
||||
}
|
||||
};
|
||||
|
|
|
@ -39,7 +39,6 @@ import {
|
|||
|
||||
describe('import timelines', () => {
|
||||
let server: ReturnType<typeof serverMock.create>;
|
||||
let request: ReturnType<typeof requestMock.create>;
|
||||
let securitySetup: SecurityPluginSetup;
|
||||
let { context } = requestContextMock.createTools();
|
||||
let mockGetTimeline: jest.Mock;
|
||||
|
@ -452,48 +451,6 @@ describe('import timelines', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('request validation', () => {
|
||||
beforeEach(() => {
|
||||
jest.doMock('../../../saved_object/timelines', () => {
|
||||
return {
|
||||
getTimelineOrNull: mockGetTimeline.mockReturnValue(null),
|
||||
persistTimeline: mockPersistTimeline.mockReturnValue({
|
||||
timeline: { savedObjectId: '79deb4c0-6bc1-11ea-9999-f5341fb7a189' },
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
jest.doMock('../../../saved_object/pinned_events', () => {
|
||||
return {
|
||||
savePinnedEvents: mockPersistPinnedEventOnTimeline.mockReturnValue(
|
||||
new Error('Test error')
|
||||
),
|
||||
};
|
||||
});
|
||||
|
||||
jest.doMock('../../../saved_object/notes/saved_object', () => {
|
||||
return {
|
||||
persistNote: mockPersistNote,
|
||||
};
|
||||
});
|
||||
});
|
||||
test('disallows invalid query', async () => {
|
||||
request = requestMock.create({
|
||||
method: 'post',
|
||||
path: TIMELINE_EXPORT_URL,
|
||||
body: { id: 'someId' },
|
||||
});
|
||||
const importTimelinesRoute = jest.requireActual('.').importTimelinesRoute;
|
||||
|
||||
importTimelinesRoute(server.router, createMockConfig(), securitySetup);
|
||||
const result = server.validate(request);
|
||||
|
||||
expect(result.badRequest).toHaveBeenCalledWith(
|
||||
'Invalid value {"id":"someId"}, excess properties: ["id"]'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('import timeline templates', () => {
|
||||
|
@ -904,7 +861,7 @@ describe('import timeline templates', () => {
|
|||
request = requestMock.create({
|
||||
method: 'post',
|
||||
path: TIMELINE_EXPORT_URL,
|
||||
body: { id: 'someId' },
|
||||
body: { isImmutable: 1 },
|
||||
});
|
||||
const importTimelinesRoute = jest.requireActual('.').importTimelinesRoute;
|
||||
|
||||
|
@ -912,7 +869,7 @@ describe('import timeline templates', () => {
|
|||
const result = server.validate(request);
|
||||
|
||||
expect(result.badRequest).toHaveBeenCalledWith(
|
||||
'Invalid value {"id":"someId"}, excess properties: ["id"]'
|
||||
"isImmutable: Expected 'true' | 'false', received number"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,18 +7,23 @@
|
|||
|
||||
import { extname } from 'path';
|
||||
import type { Readable } from 'stream';
|
||||
import { get } from 'lodash/fp';
|
||||
|
||||
import type { IKibanaResponse } from '@kbn/core-http-server';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import type { SecuritySolutionPluginRouter } from '../../../../../types';
|
||||
|
||||
import { TIMELINE_IMPORT_URL } from '../../../../../../common/constants';
|
||||
|
||||
import type { ConfigType } from '../../../../../config';
|
||||
import { buildRouteValidationWithExcess } from '../../../../../utils/build_validation/route_validation';
|
||||
import { buildSiemResponse } from '../../../../detection_engine/routes/utils';
|
||||
|
||||
import { importTimelines } from './helpers';
|
||||
import { ImportTimelinesPayloadSchemaRt } from '../../../../../../common/api/timeline';
|
||||
import {
|
||||
ImportTimelinesRequestBody,
|
||||
type ImportTimelinesResponse,
|
||||
} from '../../../../../../common/api/timeline';
|
||||
import { buildFrameworkRequest } from '../../../utils/common';
|
||||
|
||||
export { importTimelines } from './helpers';
|
||||
|
@ -39,11 +44,13 @@ export const importTimelinesRoute = (router: SecuritySolutionPluginRouter, confi
|
|||
.addVersion(
|
||||
{
|
||||
validate: {
|
||||
request: { body: buildRouteValidationWithExcess(ImportTimelinesPayloadSchemaRt) },
|
||||
request: {
|
||||
body: buildRouteValidationWithZod(ImportTimelinesRequestBody),
|
||||
},
|
||||
},
|
||||
version: '2023-10-31',
|
||||
},
|
||||
async (context, request, response) => {
|
||||
async (context, request, response): Promise<IKibanaResponse<ImportTimelinesResponse>> => {
|
||||
try {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
const savedObjectsClient = (await context.core).savedObjects.client;
|
||||
|
@ -52,7 +59,7 @@ export const importTimelinesRoute = (router: SecuritySolutionPluginRouter, confi
|
|||
}
|
||||
|
||||
const { file, isImmutable } = request.body;
|
||||
const { filename } = file.hapi;
|
||||
const filename = extractFilename(file);
|
||||
const fileExtension = extname(filename).toLowerCase();
|
||||
|
||||
if (fileExtension !== '.ndjson') {
|
||||
|
@ -69,8 +76,11 @@ export const importTimelinesRoute = (router: SecuritySolutionPluginRouter, confi
|
|||
frameworkRequest,
|
||||
isImmutable === 'true'
|
||||
);
|
||||
if (typeof res !== 'string') return response.ok({ body: res ?? {} });
|
||||
else throw res;
|
||||
if (res instanceof Error || typeof res === 'string') {
|
||||
throw res;
|
||||
} else {
|
||||
return response.ok({ body: res ?? {} });
|
||||
}
|
||||
} catch (err) {
|
||||
const error = transformError(err);
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
@ -82,3 +92,11 @@ export const importTimelinesRoute = (router: SecuritySolutionPluginRouter, confi
|
|||
}
|
||||
);
|
||||
};
|
||||
|
||||
function extractFilename(fileObj: unknown) {
|
||||
const filename = get('hapi.filename', fileObj);
|
||||
if (filename && typeof filename === 'string') {
|
||||
return filename;
|
||||
}
|
||||
throw new Error('`filename` missing in file');
|
||||
}
|
||||
|
|
|
@ -7,22 +7,22 @@
|
|||
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import type { IKibanaResponse } from '@kbn/core/server';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
import type { SecuritySolutionPluginRouter } from '../../../../../types';
|
||||
|
||||
import { TIMELINE_URL } from '../../../../../../common/constants';
|
||||
|
||||
import { buildRouteValidationWithExcess } from '../../../../../utils/build_validation/route_validation';
|
||||
import type { ConfigType } from '../../../../..';
|
||||
|
||||
import { buildSiemResponse } from '../../../../detection_engine/routes/utils';
|
||||
|
||||
import { patchTimelineSchema } from '../../../../../../common/api/timeline';
|
||||
import {
|
||||
PatchTimelineRequestBody,
|
||||
type PatchTimelineResponse,
|
||||
} from '../../../../../../common/api/timeline';
|
||||
import { buildFrameworkRequest, TimelineStatusActions } from '../../../utils/common';
|
||||
import { createTimelines } from '../create_timelines';
|
||||
import { CompareTimelinesStatus } from '../../../utils/compare_timelines_status';
|
||||
import type { PatchTimelinesResponse } from '../../../../../../common/api/timeline';
|
||||
|
||||
export const patchTimelinesRoute = (router: SecuritySolutionPluginRouter, _: ConfigType) => {
|
||||
export const patchTimelinesRoute = (router: SecuritySolutionPluginRouter) => {
|
||||
router.versioned
|
||||
.patch({
|
||||
path: TIMELINE_URL,
|
||||
|
@ -34,11 +34,11 @@ export const patchTimelinesRoute = (router: SecuritySolutionPluginRouter, _: Con
|
|||
.addVersion(
|
||||
{
|
||||
validate: {
|
||||
request: { body: buildRouteValidationWithExcess(patchTimelineSchema) },
|
||||
request: { body: buildRouteValidationWithZod(PatchTimelineRequestBody) },
|
||||
},
|
||||
version: '2023-10-31',
|
||||
},
|
||||
async (context, request, response): Promise<IKibanaResponse<PatchTimelinesResponse>> => {
|
||||
async (context, request, response): Promise<IKibanaResponse<PatchTimelineResponse>> => {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
try {
|
||||
|
|
|
@ -5,14 +5,13 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { IKibanaResponse } from '@kbn/core-http-server';
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
import type { SecuritySolutionPluginRouter } from '../../../../../types';
|
||||
|
||||
import { TIMELINE_FAVORITE_URL } from '../../../../../../common/constants';
|
||||
|
||||
import type { ConfigType } from '../../../../..';
|
||||
|
||||
import { buildSiemResponse } from '../../../../detection_engine/routes/utils';
|
||||
|
||||
import { buildFrameworkRequest } from '../../../utils/common';
|
||||
|
@ -23,7 +22,7 @@ import {
|
|||
TimelineTypeEnum,
|
||||
} from '../../../../../../common/api/timeline';
|
||||
|
||||
export const persistFavoriteRoute = (router: SecuritySolutionPluginRouter, _: ConfigType) => {
|
||||
export const persistFavoriteRoute = (router: SecuritySolutionPluginRouter) => {
|
||||
router.versioned
|
||||
.patch({
|
||||
path: TIMELINE_FAVORITE_URL,
|
||||
|
@ -39,7 +38,11 @@ export const persistFavoriteRoute = (router: SecuritySolutionPluginRouter, _: Co
|
|||
request: { body: buildRouteValidationWithZod(PersistFavoriteRouteRequestBody) },
|
||||
},
|
||||
},
|
||||
async (context, request, response) => {
|
||||
async (
|
||||
context,
|
||||
request,
|
||||
response
|
||||
): Promise<IKibanaResponse<PersistFavoriteRouteResponse>> => {
|
||||
const siemResponse = buildSiemResponse(response);
|
||||
|
||||
try {
|
||||
|
|
|
@ -6,24 +6,24 @@
|
|||
*/
|
||||
|
||||
import { transformError } from '@kbn/securitysolution-es-utils';
|
||||
import type { IKibanaResponse } from '@kbn/core-http-server';
|
||||
import { buildRouteValidationWithZod } from '@kbn/zod-helpers';
|
||||
|
||||
import type { SecuritySolutionPluginRouter } from '../../../../../types';
|
||||
|
||||
import { TIMELINE_RESOLVE_URL } from '../../../../../../common/constants';
|
||||
|
||||
import type { ConfigType } from '../../../../..';
|
||||
import { buildRouteValidationWithExcess } from '../../../../../utils/build_validation/route_validation';
|
||||
|
||||
import { buildSiemResponse } from '../../../../detection_engine/routes/utils';
|
||||
|
||||
import { buildFrameworkRequest } from '../../../utils/common';
|
||||
import { getTimelineQuerySchema } from '../../../../../../common/api/timeline';
|
||||
import { getTimelineTemplateOrNull, resolveTimelineOrNull } from '../../../saved_object/timelines';
|
||||
import type {
|
||||
SavedTimeline,
|
||||
ResolvedTimelineWithOutcomeSavedObject,
|
||||
import {
|
||||
ResolveTimelineRequestQuery,
|
||||
type ResolveTimelineResponse,
|
||||
} from '../../../../../../common/api/timeline';
|
||||
import { getTimelineTemplateOrNull, resolveTimelineOrNull } from '../../../saved_object/timelines';
|
||||
import type { SavedTimeline, ResolvedTimeline } from '../../../../../../common/api/timeline';
|
||||
|
||||
export const resolveTimelineRoute = (router: SecuritySolutionPluginRouter, _: ConfigType) => {
|
||||
export const resolveTimelineRoute = (router: SecuritySolutionPluginRouter) => {
|
||||
router.versioned
|
||||
.get({
|
||||
path: TIMELINE_RESOLVE_URL,
|
||||
|
@ -36,16 +36,16 @@ export const resolveTimelineRoute = (router: SecuritySolutionPluginRouter, _: Co
|
|||
{
|
||||
version: '2023-10-31',
|
||||
validate: {
|
||||
request: { query: buildRouteValidationWithExcess(getTimelineQuerySchema) },
|
||||
request: { query: buildRouteValidationWithZod(ResolveTimelineRequestQuery) },
|
||||
},
|
||||
},
|
||||
async (context, request, response) => {
|
||||
async (context, request, response): Promise<IKibanaResponse<ResolveTimelineResponse>> => {
|
||||
try {
|
||||
const frameworkRequest = await buildFrameworkRequest(context, request);
|
||||
const query = request.query ?? {};
|
||||
const { template_timeline_id: templateTimelineId, id } = query;
|
||||
|
||||
let res: SavedTimeline | ResolvedTimelineWithOutcomeSavedObject | null = null;
|
||||
let res: SavedTimeline | ResolvedTimeline | null = null;
|
||||
|
||||
if (templateTimelineId != null && id == null) {
|
||||
// Template timelineId is not a SO id, so it does not need to be updated to use resolve
|
||||
|
|
|
@ -13,7 +13,7 @@ import type { Note } from '../../../../../common/api/timeline';
|
|||
export const persistNotes = async (
|
||||
frameworkRequest: FrameworkRequest,
|
||||
timelineSavedObjectId: string,
|
||||
existingNoteIds?: string[],
|
||||
existingNoteIds?: string[] | null,
|
||||
newNotes?: Note[],
|
||||
overrideOwner: boolean = true
|
||||
) => {
|
||||
|
|
|
@ -16,7 +16,7 @@ import {
|
|||
SavedObjectTimelineType,
|
||||
SavedObjectTimelineStatus,
|
||||
} from '../../../../../common/types/timeline/saved_object';
|
||||
import type { TimelineSavedObject } from '../../../../../common/api/timeline';
|
||||
import type { TimelineResponse } from '../../../../../common/api/timeline';
|
||||
import {
|
||||
type TimelineType,
|
||||
TimelineTypeEnum,
|
||||
|
@ -49,7 +49,7 @@ const getTimelineTypeAndStatus = (
|
|||
};
|
||||
};
|
||||
|
||||
export const convertSavedObjectToSavedTimeline = (savedObject: unknown): TimelineSavedObject =>
|
||||
export const convertSavedObjectToSavedTimeline = (savedObject: unknown): TimelineResponse =>
|
||||
pipe(
|
||||
TimelineSavedObjectWithDraftRuntime.decode(savedObject),
|
||||
map((savedTimeline) => {
|
||||
|
|
|
@ -23,8 +23,8 @@ import { getNotesByTimelineId, persistNote } from '../notes/saved_object';
|
|||
import { getAllPinnedEventsByTimelineId, persistPinnedEventOnTimeline } from '../pinned_events';
|
||||
import { TimelineTypeEnum } from '../../../../../common/api/timeline';
|
||||
import type {
|
||||
AllTimelinesResponse,
|
||||
ResolvedTimelineWithOutcomeSavedObject,
|
||||
GetTimelinesResponse,
|
||||
ResolvedTimeline,
|
||||
SavedTimeline,
|
||||
} from '../../../../../common/api/timeline';
|
||||
import {
|
||||
|
@ -141,7 +141,7 @@ describe('saved_object', () => {
|
|||
pageSize: 10,
|
||||
pageIndex: 1,
|
||||
};
|
||||
let result = null as unknown as AllTimelinesResponse;
|
||||
let result = null as unknown as GetTimelinesResponse;
|
||||
beforeEach(async () => {
|
||||
(convertSavedObjectToSavedTimeline as jest.Mock).mockReturnValue(mockGetTimelineValue);
|
||||
mockFindSavedObject = jest
|
||||
|
@ -275,7 +275,7 @@ describe('saved_object', () => {
|
|||
describe('resolveTimelineOrNull', () => {
|
||||
let mockResolveSavedObject: jest.Mock;
|
||||
let mockRequest: FrameworkRequest;
|
||||
let result: ResolvedTimelineWithOutcomeSavedObject | null = null;
|
||||
let result: ResolvedTimeline | null = null;
|
||||
beforeEach(async () => {
|
||||
(convertSavedObjectToSavedTimeline as jest.Mock).mockReturnValue(mockResolvedTimeline);
|
||||
mockResolveSavedObject = jest.fn().mockReturnValue(mockResolvedSavedObject);
|
||||
|
|
|
@ -19,20 +19,17 @@ import type {
|
|||
Note,
|
||||
BareNote,
|
||||
PinnedEvent,
|
||||
AllTimelinesResponse,
|
||||
GetTimelinesResponse,
|
||||
ExportTimelineNotFoundError,
|
||||
PageInfoTimeline,
|
||||
ResponseTimelines,
|
||||
FavoriteTimelineResponse,
|
||||
ResponseTimeline,
|
||||
SortTimeline,
|
||||
TimelineResult,
|
||||
TimelineResponse,
|
||||
TimelineType,
|
||||
TimelineStatus,
|
||||
ResolvedTimelineWithOutcomeSavedObject,
|
||||
TimelineSavedObject,
|
||||
ResolvedTimeline,
|
||||
SavedTimeline,
|
||||
TimelineWithoutExternalRefs,
|
||||
SavedTimelineWithSavedObjectId,
|
||||
} from '../../../../../common/api/timeline';
|
||||
import { TimelineStatusEnum, TimelineTypeEnum } from '../../../../../common/api/timeline';
|
||||
import type { SavedObjectTimelineWithoutExternalRefs } from '../../../../../common/types/timeline/saved_object';
|
||||
|
@ -49,11 +46,13 @@ import { timelineFieldsMigrator } from './field_migrator';
|
|||
export { pickSavedTimeline } from './pick_saved_timeline';
|
||||
export { convertSavedObjectToSavedTimeline } from './convert_saved_object_to_savedtimeline';
|
||||
|
||||
type TimelineWithoutExternalRefs = Omit<SavedTimeline, 'dataViewId' | 'savedQueryId'>;
|
||||
|
||||
export const getTimeline = async (
|
||||
request: FrameworkRequest,
|
||||
timelineId: string,
|
||||
timelineType: TimelineType | null = TimelineTypeEnum.default
|
||||
): Promise<TimelineSavedObject> => {
|
||||
): Promise<TimelineResponse> => {
|
||||
let timelineIdToUse = timelineId;
|
||||
try {
|
||||
if (timelineType === TimelineTypeEnum.template) {
|
||||
|
@ -77,7 +76,7 @@ export const getTimeline = async (
|
|||
export const getTimelineOrNull = async (
|
||||
frameworkRequest: FrameworkRequest,
|
||||
savedObjectId: string
|
||||
): Promise<TimelineSavedObject | null> => {
|
||||
): Promise<TimelineResponse | null> => {
|
||||
let timeline = null;
|
||||
try {
|
||||
timeline = await getTimeline(frameworkRequest, savedObjectId);
|
||||
|
@ -89,23 +88,19 @@ export const getTimelineOrNull = async (
|
|||
export const resolveTimelineOrNull = async (
|
||||
frameworkRequest: FrameworkRequest,
|
||||
savedObjectId: string
|
||||
): Promise<ResolvedTimelineWithOutcomeSavedObject | null> => {
|
||||
let resolvedTimeline = null;
|
||||
): Promise<ResolvedTimeline | null> => {
|
||||
try {
|
||||
resolvedTimeline = await resolveSavedTimeline(frameworkRequest, savedObjectId);
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (e) {}
|
||||
return resolvedTimeline;
|
||||
// }
|
||||
const resolvedTimeline = await resolveSavedTimeline(frameworkRequest, savedObjectId);
|
||||
return resolvedTimeline;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export const getTimelineByTemplateTimelineId = async (
|
||||
request: FrameworkRequest,
|
||||
templateTimelineId: string
|
||||
): Promise<{
|
||||
totalCount: number;
|
||||
timeline: TimelineSavedObject[];
|
||||
}> => {
|
||||
): Promise<GetTimelinesResponse> => {
|
||||
const options: SavedObjectsFindOptions = {
|
||||
type: timelineSavedObjectType,
|
||||
filter: `siem-ui-timeline.attributes.templateTimelineId: "${templateTimelineId}"`,
|
||||
|
@ -117,7 +112,7 @@ export const getTimelineByTemplateTimelineId = async (
|
|||
export const getTimelineTemplateOrNull = async (
|
||||
frameworkRequest: FrameworkRequest,
|
||||
templateTimelineId: string
|
||||
): Promise<TimelineSavedObject | null> => {
|
||||
): Promise<TimelineResponse | null> => {
|
||||
let templateTimeline = null;
|
||||
try {
|
||||
templateTimeline = await getTimelineByTemplateTimelineId(frameworkRequest, templateTimelineId);
|
||||
|
@ -190,10 +185,7 @@ export const getExistingPrepackagedTimelines = async (
|
|||
request: FrameworkRequest,
|
||||
countsOnly?: boolean,
|
||||
pageInfo?: PageInfoTimeline
|
||||
): Promise<{
|
||||
totalCount: number;
|
||||
timeline: TimelineSavedObject[];
|
||||
}> => {
|
||||
): Promise<GetTimelinesResponse> => {
|
||||
const queryPageInfo =
|
||||
countsOnly && pageInfo == null
|
||||
? {
|
||||
|
@ -218,7 +210,7 @@ export const getAllTimeline = async (
|
|||
sort: SortTimeline | null,
|
||||
status: TimelineStatus | null,
|
||||
timelineType: TimelineType | null
|
||||
): Promise<AllTimelinesResponse> => {
|
||||
): Promise<GetTimelinesResponse> => {
|
||||
const searchTerm = search != null ? search : undefined;
|
||||
const searchFields = ['title', 'description'];
|
||||
const filter = combineFilters([
|
||||
|
@ -291,7 +283,7 @@ export const getAllTimeline = async (
|
|||
export const getDraftTimeline = async (
|
||||
request: FrameworkRequest,
|
||||
timelineType: TimelineType | null
|
||||
): Promise<ResponseTimelines> => {
|
||||
): Promise<GetTimelinesResponse> => {
|
||||
const filter = combineFilters([
|
||||
getTimelineTypeFilter(timelineType ?? null, TimelineStatusEnum.draft),
|
||||
getTimelinesCreatedAndUpdatedByCurrentUser({ request }),
|
||||
|
@ -385,13 +377,19 @@ export const persistFavorite = async (
|
|||
}
|
||||
};
|
||||
|
||||
export interface InternalTimelineResponse {
|
||||
code: number;
|
||||
message: string;
|
||||
timeline: TimelineResponse;
|
||||
}
|
||||
|
||||
export const persistTimeline = async (
|
||||
request: FrameworkRequest,
|
||||
timelineId: string | null,
|
||||
version: string | null,
|
||||
timeline: SavedTimeline,
|
||||
isImmutable?: boolean
|
||||
): Promise<ResponseTimeline> => {
|
||||
): Promise<InternalTimelineResponse> => {
|
||||
const savedObjectsClient = (await request.context.core).savedObjects.client;
|
||||
const userInfo = isImmutable ? ({ username: 'Elastic' } as AuthenticatedUser) : request.user;
|
||||
try {
|
||||
|
@ -414,7 +412,7 @@ export const persistTimeline = async (
|
|||
timeline: await getSavedTimeline(request, timelineId),
|
||||
};
|
||||
} else if (getOr(null, 'output.statusCode', err) === 403) {
|
||||
const timelineToReturn: TimelineResult = {
|
||||
const timelineToReturn: TimelineResponse = {
|
||||
...timeline,
|
||||
savedObjectId: '',
|
||||
version: '',
|
||||
|
@ -439,7 +437,7 @@ export const createTimeline = async ({
|
|||
timeline: SavedTimeline;
|
||||
savedObjectsClient: SavedObjectsClientContract;
|
||||
userInfo: AuthenticatedUser | null;
|
||||
}) => {
|
||||
}): Promise<InternalTimelineResponse> => {
|
||||
const { transformedFields: migratedAttributes, references } =
|
||||
timelineFieldsMigrator.extractFieldsToReferences<TimelineWithoutExternalRefs>({
|
||||
data: pickSavedTimeline(timelineId, timeline, userInfo),
|
||||
|
@ -479,7 +477,7 @@ const updateTimeline = async ({
|
|||
savedObjectsClient: SavedObjectsClientContract;
|
||||
userInfo: AuthenticatedUser | null;
|
||||
version: string | null;
|
||||
}) => {
|
||||
}): Promise<InternalTimelineResponse> => {
|
||||
const rawTimelineSavedObject =
|
||||
await savedObjectsClient.get<SavedObjectTimelineWithoutExternalRefs>(
|
||||
timelineSavedObjectType,
|
||||
|
@ -516,11 +514,12 @@ export const updatePartialSavedTimeline = async (
|
|||
timelineId
|
||||
);
|
||||
|
||||
const { transformedFields, references } =
|
||||
timelineFieldsMigrator.extractFieldsToReferences<TimelineWithoutExternalRefs>({
|
||||
data: timeline,
|
||||
existingReferences: currentSavedTimeline.references,
|
||||
});
|
||||
const { transformedFields, references } = timelineFieldsMigrator.extractFieldsToReferences<
|
||||
Omit<SavedTimelineWithSavedObjectId, 'dataViewId' | 'savedQueryId'>
|
||||
>({
|
||||
data: timeline,
|
||||
existingReferences: currentSavedTimeline.references,
|
||||
});
|
||||
|
||||
const timelineUpdateAttributes = pickSavedTimeline(
|
||||
null,
|
||||
|
@ -588,7 +587,7 @@ export const copyTimeline = async (
|
|||
request: FrameworkRequest,
|
||||
timeline: SavedTimeline,
|
||||
timelineId: string
|
||||
): Promise<ResponseTimeline> => {
|
||||
): Promise<InternalTimelineResponse> => {
|
||||
const savedObjectsClient = (await request.context.core).savedObjects.client;
|
||||
|
||||
// Fetch all objects that need to be copied
|
||||
|
@ -658,7 +657,10 @@ const resolveBasicSavedTimeline = async (request: FrameworkRequest, timelineId:
|
|||
};
|
||||
};
|
||||
|
||||
const resolveSavedTimeline = async (request: FrameworkRequest, timelineId: string) => {
|
||||
const resolveSavedTimeline = async (
|
||||
request: FrameworkRequest,
|
||||
timelineId: string
|
||||
): Promise<ResolvedTimeline> => {
|
||||
const userName = request.user?.username ?? UNAUTHENTICATED_USER;
|
||||
|
||||
const { resolvedTimelineSavedObject, ...resolveAttributes } = await resolveBasicSavedTimeline(
|
||||
|
@ -673,7 +675,6 @@ const resolveSavedTimeline = async (request: FrameworkRequest, timelineId: strin
|
|||
]);
|
||||
|
||||
const [notes, pinnedEvents, timeline] = timelineWithNotesAndPinnedEvents;
|
||||
|
||||
return {
|
||||
timeline: timelineWithReduxProperties(notes, pinnedEvents, timeline, userName),
|
||||
...resolveAttributes,
|
||||
|
@ -742,9 +743,9 @@ export const convertStringToBase64 = (text: string): string => Buffer.from(text)
|
|||
export const timelineWithReduxProperties = (
|
||||
notes: Note[],
|
||||
pinnedEvents: PinnedEvent[],
|
||||
timeline: TimelineSavedObject,
|
||||
timeline: TimelineResponse,
|
||||
userName: string
|
||||
): TimelineSavedObject => ({
|
||||
): TimelineResponse => ({
|
||||
...timeline,
|
||||
favorite:
|
||||
timeline.favorite != null && userName != null
|
||||
|
@ -789,7 +790,7 @@ export const getSelectedTimelines = async (
|
|||
);
|
||||
|
||||
const timelineObjects: {
|
||||
timelines: TimelineSavedObject[];
|
||||
timelines: TimelineResponse[];
|
||||
errors: ExportTimelineNotFoundError[];
|
||||
} = savedObjects.saved_objects.reduce(
|
||||
(acc, savedObject) => {
|
||||
|
@ -805,7 +806,7 @@ export const getSelectedTimelines = async (
|
|||
return { errors: [...acc.errors, savedObject.error], timelines: acc.timelines };
|
||||
},
|
||||
{
|
||||
timelines: [] as TimelineSavedObject[],
|
||||
timelines: [] as TimelineResponse[],
|
||||
errors: [] as ExportTimelineNotFoundError[],
|
||||
}
|
||||
);
|
||||
|
|
|
@ -9,14 +9,14 @@ import { isEmpty } from 'lodash/fp';
|
|||
import type { AuthenticatedUser } from '@kbn/security-plugin/common';
|
||||
import { getUserDisplayName } from '@kbn/user-profile-components';
|
||||
import { UNAUTHENTICATED_USER } from '../../../../../common/constants';
|
||||
import type { SavedTimelineWithSavedObjectId } from '../../../../../common/api/timeline';
|
||||
import type { SavedTimeline } from '../../../../../common/api/timeline';
|
||||
import { TimelineTypeEnum, TimelineStatusEnum } from '../../../../../common/api/timeline';
|
||||
|
||||
export const pickSavedTimeline = (
|
||||
timelineId: string | null,
|
||||
savedTimeline: SavedTimelineWithSavedObjectId,
|
||||
savedTimeline: SavedTimeline,
|
||||
userInfo: AuthenticatedUser | null
|
||||
): SavedTimelineWithSavedObjectId => {
|
||||
): SavedTimeline => {
|
||||
const dateNow = new Date().valueOf();
|
||||
|
||||
if (timelineId == null) {
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
import path, { join, resolve } from 'path';
|
||||
import type {
|
||||
CheckTimelineStatusRt,
|
||||
TimelineSavedObject,
|
||||
ImportTimelinesSchema,
|
||||
TimelineResponse,
|
||||
ImportTimelines,
|
||||
InstallPrepackedTimelinesRequestBody,
|
||||
} from '../../../../common/api/timeline';
|
||||
|
||||
import type { FrameworkRequest } from '../../framework';
|
||||
|
@ -19,9 +19,9 @@ import { getExistingPrepackagedTimelines } from '../saved_object/timelines';
|
|||
import { loadData, getReadables } from './common';
|
||||
|
||||
export const getTimelinesToUpdate = (
|
||||
timelinesFromFileSystem: ImportTimelinesSchema[],
|
||||
installedTimelines: TimelineSavedObject[]
|
||||
): ImportTimelinesSchema[] => {
|
||||
timelinesFromFileSystem: ImportTimelines[],
|
||||
installedTimelines: TimelineResponse[]
|
||||
): ImportTimelines[] => {
|
||||
return timelinesFromFileSystem.filter((timeline) =>
|
||||
installedTimelines.some((installedTimeline) => {
|
||||
return (
|
||||
|
@ -34,9 +34,9 @@ export const getTimelinesToUpdate = (
|
|||
};
|
||||
|
||||
export const getTimelinesToInstall = (
|
||||
timelinesFromFileSystem: ImportTimelinesSchema[],
|
||||
installedTimelines: TimelineSavedObject[]
|
||||
): ImportTimelinesSchema[] => {
|
||||
timelinesFromFileSystem: ImportTimelines[],
|
||||
installedTimelines: TimelineResponse[]
|
||||
): ImportTimelines[] => {
|
||||
return timelinesFromFileSystem.filter(
|
||||
(timeline) =>
|
||||
!installedTimelines.some(
|
||||
|
@ -49,11 +49,11 @@ export const checkTimelinesStatus = async (
|
|||
frameworkRequest: FrameworkRequest,
|
||||
filePath?: string,
|
||||
fileName?: string
|
||||
): Promise<CheckTimelineStatusRt | Error> => {
|
||||
): Promise<InstallPrepackedTimelinesRequestBody | Error> => {
|
||||
let readStream;
|
||||
let timeline: {
|
||||
totalCount: number;
|
||||
timeline: TimelineSavedObject[];
|
||||
timeline: TimelineResponse[];
|
||||
};
|
||||
const dir = resolve(
|
||||
join(
|
||||
|
@ -75,7 +75,7 @@ export const checkTimelinesStatus = async (
|
|||
};
|
||||
}
|
||||
|
||||
return loadData<'utf-8', CheckTimelineStatusRt>(
|
||||
return loadData<'utf-8', InstallPrepackedTimelinesRequestBody>(
|
||||
readStream,
|
||||
<T>(timelinesFromFileSystem: T) => {
|
||||
if (Array.isArray(timelinesFromFileSystem)) {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import type * as rt from 'io-ts';
|
||||
|
||||
import { set } from '@kbn/safer-lodash-set/fp';
|
||||
import readline from 'readline';
|
||||
import fs from 'fs';
|
||||
|
@ -13,7 +13,6 @@ import { createListStream } from '@kbn/utils';
|
|||
import { schema } from '@kbn/config-schema';
|
||||
|
||||
import type { KibanaRequest, RequestHandlerContext } from '@kbn/core/server';
|
||||
import { formatErrors } from '@kbn/securitysolution-io-ts-utils';
|
||||
|
||||
import type { FrameworkRequest } from '../../framework';
|
||||
|
||||
|
@ -38,12 +37,6 @@ export const buildFrameworkRequest = async (
|
|||
|
||||
export const escapeHatch = schema.object({}, { unknowns: 'allow' });
|
||||
|
||||
type ErrorFactory = (message: string) => Error;
|
||||
|
||||
export const throwErrors = (createError: ErrorFactory) => (errors: rt.Errors) => {
|
||||
throw createError(formatErrors(errors).join('\n'));
|
||||
};
|
||||
|
||||
export const getReadables = (dataPath: string): Promise<Readable> =>
|
||||
new Promise((resolved, reject) => {
|
||||
const contents: string[] = [];
|
||||
|
|
|
@ -26,7 +26,7 @@ import {
|
|||
NOT_ALLOW_UPDATE_STATUS_ERROR_MESSAGE,
|
||||
TEMPLATE_TIMELINE_VERSION_CONFLICT_MESSAGE,
|
||||
} from './failure_cases';
|
||||
import type { TimelineSavedObject } from '../../../../common/api/timeline';
|
||||
import type { TimelineResponse } from '../../../../common/api/timeline';
|
||||
import { TimelineStatusEnum, TimelineTypeEnum } from '../../../../common/api/timeline';
|
||||
import { mockGetTimelineValue, mockGetTemplateTimelineValue } from '../__mocks__/import_timelines';
|
||||
|
||||
|
@ -69,7 +69,7 @@ describe('failure cases', () => {
|
|||
const version = null;
|
||||
const templateTimelineVersion = null;
|
||||
const templateTimelineId = null;
|
||||
const existTimeline = mockGetTimelineValue as TimelineSavedObject;
|
||||
const existTimeline = mockGetTimelineValue as TimelineResponse;
|
||||
const existTemplateTimeline = null;
|
||||
const result = checkIsCreateFailureCases(
|
||||
isHandlingTemplateTimeline,
|
||||
|
@ -94,7 +94,7 @@ describe('failure cases', () => {
|
|||
const templateTimelineVersion = 1;
|
||||
const templateTimelineId = 'template-timeline-id-one';
|
||||
const existTimeline = null;
|
||||
const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineSavedObject;
|
||||
const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineResponse;
|
||||
const result = checkIsCreateFailureCases(
|
||||
isHandlingTemplateTimeline,
|
||||
TimelineStatusEnum.active,
|
||||
|
@ -144,7 +144,7 @@ describe('failure cases', () => {
|
|||
const templateTimelineVersion = null;
|
||||
const templateTimelineId = null;
|
||||
const existTimeline = {
|
||||
...(mockGetTimelineValue as TimelineSavedObject),
|
||||
...(mockGetTimelineValue as TimelineResponse),
|
||||
status: TimelineStatusEnum.immutable,
|
||||
};
|
||||
const existTemplateTimeline = null;
|
||||
|
@ -172,7 +172,7 @@ describe('failure cases', () => {
|
|||
const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId;
|
||||
const existTimeline = null;
|
||||
const existTemplateTimeline = {
|
||||
...(mockGetTemplateTimelineValue as TimelineSavedObject),
|
||||
...(mockGetTemplateTimelineValue as TimelineResponse),
|
||||
status: TimelineStatusEnum.immutable,
|
||||
};
|
||||
const result = checkIsUpdateFailureCases(
|
||||
|
@ -198,7 +198,7 @@ describe('failure cases', () => {
|
|||
const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion;
|
||||
const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId;
|
||||
const existTimeline = null;
|
||||
const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineSavedObject;
|
||||
const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineResponse;
|
||||
const result = checkIsUpdateFailureCases(
|
||||
isHandlingTemplateTimeline,
|
||||
TimelineStatusEnum.active,
|
||||
|
@ -246,10 +246,10 @@ describe('failure cases', () => {
|
|||
const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion;
|
||||
const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId;
|
||||
const existTimeline = {
|
||||
...(mockGetTemplateTimelineValue as TimelineSavedObject),
|
||||
...(mockGetTemplateTimelineValue as TimelineResponse),
|
||||
savedObjectId: 'someOtherId',
|
||||
};
|
||||
const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineSavedObject;
|
||||
const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineResponse;
|
||||
const result = checkIsUpdateFailureCases(
|
||||
isHandlingTemplateTimeline,
|
||||
TimelineStatusEnum.active,
|
||||
|
@ -273,7 +273,7 @@ describe('failure cases', () => {
|
|||
const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion;
|
||||
const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId;
|
||||
const existTimeline = null;
|
||||
const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineSavedObject;
|
||||
const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineResponse;
|
||||
const result = checkIsUpdateFailureCases(
|
||||
isHandlingTemplateTimeline,
|
||||
TimelineStatusEnum.active,
|
||||
|
@ -297,7 +297,7 @@ describe('failure cases', () => {
|
|||
const templateTimelineVersion = null;
|
||||
const templateTimelineId = null;
|
||||
const existTimeline = {
|
||||
...(mockGetTemplateTimelineValue as TimelineSavedObject),
|
||||
...(mockGetTemplateTimelineValue as TimelineResponse),
|
||||
savedObjectId: 'someOtherId',
|
||||
};
|
||||
const existTemplateTimeline = null;
|
||||
|
@ -326,7 +326,7 @@ describe('failure cases', () => {
|
|||
const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion;
|
||||
const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId;
|
||||
const existTimeline = null;
|
||||
const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineSavedObject;
|
||||
const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineResponse;
|
||||
const result = checkIsCreateViaImportFailureCases(
|
||||
isHandlingTemplateTimeline,
|
||||
TimelineStatusEnum.draft,
|
||||
|
@ -350,7 +350,7 @@ describe('failure cases', () => {
|
|||
const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion;
|
||||
const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId;
|
||||
const existTimeline = null;
|
||||
const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineSavedObject;
|
||||
const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineResponse;
|
||||
const result = checkIsCreateViaImportFailureCases(
|
||||
isHandlingTemplateTimeline,
|
||||
TimelineStatusEnum.active,
|
||||
|
@ -373,7 +373,7 @@ describe('failure cases', () => {
|
|||
const version = mockGetTimelineValue.version;
|
||||
const templateTimelineVersion = null;
|
||||
const templateTimelineId = null;
|
||||
const existTimeline = mockGetTimelineValue as TimelineSavedObject;
|
||||
const existTimeline = mockGetTimelineValue as TimelineResponse;
|
||||
const existTemplateTimeline = null;
|
||||
const result = checkIsCreateViaImportFailureCases(
|
||||
isHandlingTemplateTimeline,
|
||||
|
@ -399,7 +399,7 @@ describe('failure cases', () => {
|
|||
const version = mockGetTimelineValue.version;
|
||||
const templateTimelineVersion = null;
|
||||
const templateTimelineId = null;
|
||||
const existTimeline = mockGetTimelineValue as TimelineSavedObject;
|
||||
const existTimeline = mockGetTimelineValue as TimelineResponse;
|
||||
const existTemplateTimeline = null;
|
||||
const result = checkIsUpdateViaImportFailureCases(
|
||||
isHandlingTemplateTimeline,
|
||||
|
@ -424,7 +424,7 @@ describe('failure cases', () => {
|
|||
const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion;
|
||||
const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId;
|
||||
const existTimeline = null;
|
||||
const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineSavedObject;
|
||||
const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineResponse;
|
||||
const result = checkIsUpdateViaImportFailureCases(
|
||||
isHandlingTemplateTimeline,
|
||||
TimelineStatusEnum.active,
|
||||
|
@ -448,7 +448,7 @@ describe('failure cases', () => {
|
|||
const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion;
|
||||
const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId;
|
||||
const existTimeline = null;
|
||||
const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineSavedObject;
|
||||
const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineResponse;
|
||||
const result = checkIsUpdateViaImportFailureCases(
|
||||
isHandlingTemplateTimeline,
|
||||
TimelineStatusEnum.immutable,
|
||||
|
@ -496,10 +496,10 @@ describe('failure cases', () => {
|
|||
const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion;
|
||||
const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId;
|
||||
const existTimeline = {
|
||||
...(mockGetTemplateTimelineValue as TimelineSavedObject),
|
||||
...(mockGetTemplateTimelineValue as TimelineResponse),
|
||||
savedObjectId: 'someOtherId',
|
||||
};
|
||||
const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineSavedObject;
|
||||
const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineResponse;
|
||||
const result = checkIsUpdateViaImportFailureCases(
|
||||
isHandlingTemplateTimeline,
|
||||
TimelineStatusEnum.active,
|
||||
|
@ -523,7 +523,7 @@ describe('failure cases', () => {
|
|||
const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion;
|
||||
const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId;
|
||||
const existTimeline = null;
|
||||
const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineSavedObject;
|
||||
const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineResponse;
|
||||
const result = checkIsUpdateViaImportFailureCases(
|
||||
isHandlingTemplateTimeline,
|
||||
TimelineStatusEnum.active,
|
||||
|
@ -547,7 +547,7 @@ describe('failure cases', () => {
|
|||
const templateTimelineVersion = mockGetTemplateTimelineValue.templateTimelineVersion;
|
||||
const templateTimelineId = mockGetTemplateTimelineValue.templateTimelineId;
|
||||
const existTimeline = null;
|
||||
const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineSavedObject;
|
||||
const existTemplateTimeline = mockGetTemplateTimelineValue as TimelineResponse;
|
||||
const result = checkIsUpdateViaImportFailureCases(
|
||||
isHandlingTemplateTimeline,
|
||||
TimelineStatusEnum.active,
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import { isEmpty } from 'lodash/fp';
|
||||
import type { TimelineType, TimelineSavedObject } from '../../../../common/api/timeline';
|
||||
import type { TimelineType, TimelineResponse } from '../../../../common/api/timeline';
|
||||
import { type TimelineStatus, TimelineStatusEnum } from '../../../../common/api/timeline';
|
||||
|
||||
export const UPDATE_TIMELINE_ERROR_MESSAGE =
|
||||
|
@ -42,8 +42,8 @@ export const DEFAULT_ERROR = `Something has gone wrong. We didn't handle somethi
|
|||
const isUpdatingStatus = (
|
||||
isHandlingTemplateTimeline: boolean,
|
||||
status: TimelineStatus | null | undefined,
|
||||
existTimeline: TimelineSavedObject | null,
|
||||
existTemplateTimeline: TimelineSavedObject | null
|
||||
existTimeline: TimelineResponse | null,
|
||||
existTemplateTimeline: TimelineResponse | null
|
||||
) => {
|
||||
const obj = isHandlingTemplateTimeline ? existTemplateTimeline : existTimeline;
|
||||
return obj?.status === TimelineStatusEnum.immutable ? UPDATE_STATUS_ERROR_MESSAGE : null;
|
||||
|
@ -76,8 +76,8 @@ const commonUpdateTemplateTimelineCheck = (
|
|||
version: string | null,
|
||||
templateTimelineVersion: number | null,
|
||||
templateTimelineId: string | null | undefined,
|
||||
existTimeline: TimelineSavedObject | null,
|
||||
existTemplateTimeline: TimelineSavedObject | null
|
||||
existTimeline: TimelineResponse | null,
|
||||
existTemplateTimeline: TimelineResponse | null
|
||||
) => {
|
||||
if (isHandlingTemplateTimeline) {
|
||||
if (
|
||||
|
@ -129,8 +129,8 @@ const commonUpdateTimelineCheck = (
|
|||
version: string | null,
|
||||
templateTimelineVersion: number | null,
|
||||
templateTimelineId: string | null | undefined,
|
||||
existTimeline: TimelineSavedObject | null,
|
||||
existTemplateTimeline: TimelineSavedObject | null
|
||||
existTimeline: TimelineResponse | null,
|
||||
existTemplateTimeline: TimelineResponse | null
|
||||
) => {
|
||||
if (existTimeline == null) {
|
||||
// timeline !exists
|
||||
|
@ -158,8 +158,8 @@ const commonUpdateCases = (
|
|||
version: string | null,
|
||||
templateTimelineVersion: number | null,
|
||||
templateTimelineId: string | null | undefined,
|
||||
existTimeline: TimelineSavedObject | null,
|
||||
existTemplateTimeline: TimelineSavedObject | null
|
||||
existTimeline: TimelineResponse | null,
|
||||
existTemplateTimeline: TimelineResponse | null
|
||||
) => {
|
||||
if (isHandlingTemplateTimeline) {
|
||||
return commonUpdateTemplateTimelineCheck(
|
||||
|
@ -193,8 +193,8 @@ const createTemplateTimelineCheck = (
|
|||
version: string | null,
|
||||
templateTimelineVersion: number | null,
|
||||
templateTimelineId: string | null | undefined,
|
||||
existTimeline: TimelineSavedObject | null,
|
||||
existTemplateTimeline: TimelineSavedObject | null
|
||||
existTimeline: TimelineResponse | null,
|
||||
existTemplateTimeline: TimelineResponse | null
|
||||
) => {
|
||||
if (isHandlingTemplateTimeline && existTemplateTimeline != null) {
|
||||
// Throw error to create timeline template in patch
|
||||
|
@ -219,8 +219,8 @@ export const checkIsUpdateViaImportFailureCases = (
|
|||
version: string | null,
|
||||
templateTimelineVersion: number | null,
|
||||
templateTimelineId: string | null | undefined,
|
||||
existTimeline: TimelineSavedObject | null,
|
||||
existTemplateTimeline: TimelineSavedObject | null
|
||||
existTimeline: TimelineResponse | null,
|
||||
existTemplateTimeline: TimelineResponse | null
|
||||
) => {
|
||||
if (!isHandlingTemplateTimeline) {
|
||||
if (existTimeline == null) {
|
||||
|
@ -281,8 +281,8 @@ export const checkIsUpdateFailureCases = (
|
|||
version: string | null,
|
||||
templateTimelineVersion: number | null,
|
||||
templateTimelineId: string | null | undefined,
|
||||
existTimeline: TimelineSavedObject | null,
|
||||
existTemplateTimeline: TimelineSavedObject | null
|
||||
existTimeline: TimelineResponse | null,
|
||||
existTemplateTimeline: TimelineResponse | null
|
||||
) => {
|
||||
const error = isUpdatingStatus(
|
||||
isHandlingTemplateTimeline,
|
||||
|
@ -315,8 +315,8 @@ export const checkIsCreateFailureCases = (
|
|||
version: string | null,
|
||||
templateTimelineVersion: number | null,
|
||||
templateTimelineId: string | null | undefined,
|
||||
existTimeline: TimelineSavedObject | null,
|
||||
existTemplateTimeline: TimelineSavedObject | null
|
||||
existTimeline: TimelineResponse | null,
|
||||
existTemplateTimeline: TimelineResponse | null
|
||||
) => {
|
||||
if (!isHandlingTemplateTimeline && existTimeline != null) {
|
||||
return {
|
||||
|
@ -346,8 +346,8 @@ export const checkIsCreateViaImportFailureCases = (
|
|||
version: string | null,
|
||||
templateTimelineVersion: number | null,
|
||||
templateTimelineId: string | null | undefined,
|
||||
existTimeline: TimelineSavedObject | null,
|
||||
existTemplateTimeline: TimelineSavedObject | null
|
||||
existTimeline: TimelineResponse | null,
|
||||
existTemplateTimeline: TimelineResponse | null
|
||||
) => {
|
||||
if (status === TimelineStatusEnum.draft) {
|
||||
return {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue