diff --git a/x-pack/plugins/security_solution/common/graphql/shared/schema.gql.ts b/x-pack/plugins/security_solution/common/graphql/shared/schema.gql.ts index d043c1587d3c34..546fdd68b4257a 100644 --- a/x-pack/plugins/security_solution/common/graphql/shared/schema.gql.ts +++ b/x-pack/plugins/security_solution/common/graphql/shared/schema.gql.ts @@ -11,9 +11,14 @@ export const sharedSchema = gql` "The interval string to use for last bucket. The format is '{value}{unit}'. For example '5m' would return the metrics for the last 5 minutes of the timespan." interval: String! "The end of the timerange" - to: Float! + to: String! "The beginning of the timerange" - from: Float! + from: String! + } + + input docValueFieldsInput { + field: String! + format: String! } type CursorType { diff --git a/x-pack/plugins/security_solution/common/types/timeline/index.ts b/x-pack/plugins/security_solution/common/types/timeline/index.ts index 021e5a7f00b173..98d17fc87f6ce3 100644 --- a/x-pack/plugins/security_solution/common/types/timeline/index.ts +++ b/x-pack/plugins/security_solution/common/types/timeline/index.ts @@ -124,8 +124,12 @@ const SavedFilterQueryQueryRuntimeType = runtimeTypes.partial({ * DatePicker Range Types */ const SavedDateRangePickerRuntimeType = runtimeTypes.partial({ - start: unionWithNullType(runtimeTypes.number), - end: unionWithNullType(runtimeTypes.number), + /* 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])), }); /* diff --git a/x-pack/plugins/security_solution/cypress/integration/ml_conditional_links.spec.ts b/x-pack/plugins/security_solution/cypress/integration/ml_conditional_links.spec.ts index 6b3fc9e751ea40..0b302efd655a8c 100644 --- a/x-pack/plugins/security_solution/cypress/integration/ml_conditional_links.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/ml_conditional_links.spec.ts @@ -94,7 +94,7 @@ describe('ml conditional links', () => { loginAndWaitForPageWithoutDateRange(mlNetworkSingleIpNullKqlQuery); cy.url().should( 'include', - '/app/security/network/ip/127.0.0.1/source?timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))' + '/app/security/network/ip/127.0.0.1/source?timerange=(global:(linkTo:!(timeline),timerange:(from:%272019-08-28T11:00:00.000Z%27,kind:absolute,to:%272019-08-28T13:59:59.999Z%27)),timeline:(linkTo:!(global),timerange:(from:%272019-08-28T11:00:00.000Z%27,kind:absolute,to:%272019-08-28T13:59:59.999Z%27)))' ); }); @@ -102,7 +102,7 @@ describe('ml conditional links', () => { loginAndWaitForPageWithoutDateRange(mlNetworkSingleIpKqlQuery); cy.url().should( 'include', - '/app/security/network/ip/127.0.0.1/source?query=(language:kuery,query:%27(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)%27)&timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))' + '/app/security/network/ip/127.0.0.1/source?query=(language:kuery,query:%27(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)%27)&timerange=(global:(linkTo:!(timeline),timerange:(from:%272019-08-28T11:00:00.000Z%27,kind:absolute,to:%272019-08-28T13:59:59.999Z%27)),timeline:(linkTo:!(global),timerange:(from:%272019-08-28T11:00:00.000Z%27,kind:absolute,to:%272019-08-28T13:59:59.999Z%27)))' ); }); @@ -110,7 +110,7 @@ describe('ml conditional links', () => { loginAndWaitForPageWithoutDateRange(mlNetworkMultipleIpNullKqlQuery); cy.url().should( 'include', - 'app/security/network/flows?query=(language:kuery,query:%27((source.ip:%20%22127.0.0.1%22%20or%20destination.ip:%20%22127.0.0.1%22)%20or%20(source.ip:%20%22127.0.0.2%22%20or%20destination.ip:%20%22127.0.0.2%22))%27)&timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999))' + 'app/security/network/flows?query=(language:kuery,query:%27((source.ip:%20%22127.0.0.1%22%20or%20destination.ip:%20%22127.0.0.1%22)%20or%20(source.ip:%20%22127.0.0.2%22%20or%20destination.ip:%20%22127.0.0.2%22))%27)&timerange=(global:(linkTo:!(timeline),timerange:(from:%272019-08-28T11:00:00.000Z%27,kind:absolute,to:%272019-08-28T13:59:59.999Z%27)),timeline:(linkTo:!(global),timerange:(from:%272019-08-28T11:00:00.000Z%27,kind:absolute,to:%272019-08-28T13:59:59.999Z%27))' ); }); @@ -118,7 +118,7 @@ describe('ml conditional links', () => { loginAndWaitForPageWithoutDateRange(mlNetworkMultipleIpKqlQuery); cy.url().should( 'include', - '/app/security/network/flows?query=(language:kuery,query:%27((source.ip:%20%22127.0.0.1%22%20or%20destination.ip:%20%22127.0.0.1%22)%20or%20(source.ip:%20%22127.0.0.2%22%20or%20destination.ip:%20%22127.0.0.2%22))%20and%20((process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22))%27)&timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))' + '/app/security/network/flows?query=(language:kuery,query:%27((source.ip:%20%22127.0.0.1%22%20or%20destination.ip:%20%22127.0.0.1%22)%20or%20(source.ip:%20%22127.0.0.2%22%20or%20destination.ip:%20%22127.0.0.2%22))%20and%20((process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22))%27)&timerange=(global:(linkTo:!(timeline),timerange:(from:%272019-08-28T11:00:00.000Z%27,kind:absolute,to:%272019-08-28T13:59:59.999Z%27)),timeline:(linkTo:!(global),timerange:(from:%272019-08-28T11:00:00.000Z%27,kind:absolute,to:%272019-08-28T13:59:59.999Z%27)))' ); }); @@ -126,7 +126,7 @@ describe('ml conditional links', () => { loginAndWaitForPageWithoutDateRange(mlNetworkNullKqlQuery); cy.url().should( 'include', - '/app/security/network/flows?timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))' + '/app/security/network/flows?timerange=(global:(linkTo:!(timeline),timerange:(from:%272019-08-28T11:00:00.000Z%27,kind:absolute,to:%272019-08-28T13:59:59.999Z%27)),timeline:(linkTo:!(global),timerange:(from:%272019-08-28T11:00:00.000Z%27,kind:absolute,to:%272019-08-28T13:59:59.999Z%27)))' ); }); @@ -134,7 +134,7 @@ describe('ml conditional links', () => { loginAndWaitForPageWithoutDateRange(mlNetworkKqlQuery); cy.url().should( 'include', - '/app/security/network/flows?query=(language:kuery,query:%27(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)%27)&timerange=(global:(linkTo:!(timeline),timerange:(from:1566990000000,kind:absolute,to:1567000799999)),timeline:(linkTo:!(global),timerange:(from:1566990000000,kind:absolute,to:1567000799999)))' + '/app/security/network/flows?query=(language:kuery,query:%27(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)%27)&timerange=(global:(linkTo:!(timeline),timerange:(from:%272019-08-28T11:00:00.000Z%27,kind:absolute,to:%272019-08-28T13:59:59.999Z%27)),timeline:(linkTo:!(global),timerange:(from:%272019-08-28T11:00:00.000Z%27,kind:absolute,to:%272019-08-28T13:59:59.999Z%27)))' ); }); @@ -142,7 +142,7 @@ describe('ml conditional links', () => { loginAndWaitForPageWithoutDateRange(mlHostSingleHostNullKqlQuery); cy.url().should( 'include', - '/app/security/hosts/siem-windows/anomalies?timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))' + '/app/security/hosts/siem-windows/anomalies?timerange=(global:(linkTo:!(timeline),timerange:(from:%272019-06-06T06:00:00.000Z%27,kind:absolute,to:%272019-06-07T05:59:59.999Z%27)),timeline:(linkTo:!(global),timerange:(from:%272019-06-06T06:00:00.000Z%27,kind:absolute,to:%272019-06-07T05:59:59.999Z%27)))' ); }); @@ -150,7 +150,7 @@ describe('ml conditional links', () => { loginAndWaitForPageWithoutDateRange(mlHostSingleHostKqlQueryVariable); cy.url().should( 'include', - '/app/security/hosts/siem-windows/anomalies?timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))' + '/app/security/hosts/siem-windows/anomalies?timerange=(global:(linkTo:!(timeline),timerange:(from:%272019-06-06T06:00:00.000Z%27,kind:absolute,to:%272019-06-07T05:59:59.999Z%27)),timeline:(linkTo:!(global),timerange:(from:%272019-06-06T06:00:00.000Z%27,kind:absolute,to:%272019-06-07T05:59:59.999Z%27)))' ); }); @@ -158,7 +158,7 @@ describe('ml conditional links', () => { loginAndWaitForPageWithoutDateRange(mlHostSingleHostKqlQuery); cy.url().should( 'include', - '/app/security/hosts/siem-windows/anomalies?query=(language:kuery,query:%27(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)%27)&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))' + '/app/security/hosts/siem-windows/anomalies?query=(language:kuery,query:%27(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)%27)&timerange=(global:(linkTo:!(timeline),timerange:(from:%272019-06-06T06:00:00.000Z%27,kind:absolute,to:%272019-06-07T05:59:59.999Z%27)),timeline:(linkTo:!(global),timerange:(from:%272019-06-06T06:00:00.000Z%27,kind:absolute,to:%272019-06-07T05:59:59.999Z%27)))' ); }); @@ -166,7 +166,7 @@ describe('ml conditional links', () => { loginAndWaitForPageWithoutDateRange(mlHostMultiHostNullKqlQuery); cy.url().should( 'include', - '/app/security/hosts/anomalies?query=(language:kuery,query:%27(host.name:%20%22siem-windows%22%20or%20host.name:%20%22siem-suricata%22)%27)&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))' + '/app/security/hosts/anomalies?query=(language:kuery,query:%27(host.name:%20%22siem-windows%22%20or%20host.name:%20%22siem-suricata%22)%27)&timerange=(global:(linkTo:!(timeline),timerange:(from:%272019-06-06T06:00:00.000Z%27,kind:absolute,to:%272019-06-07T05:59:59.999Z%27)),timeline:(linkTo:!(global),timerange:(from:%272019-06-06T06:00:00.000Z%27,kind:absolute,to:%272019-06-07T05:59:59.999Z%27)))' ); }); @@ -174,7 +174,7 @@ describe('ml conditional links', () => { loginAndWaitForPageWithoutDateRange(mlHostMultiHostKqlQuery); cy.url().should( 'include', - '/app/security/hosts/anomalies?query=(language:kuery,query:%27(host.name:%20%22siem-windows%22%20or%20host.name:%20%22siem-suricata%22)%20and%20((process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22))%27)&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))' + '/app/security/hosts/anomalies?query=(language:kuery,query:%27(host.name:%20%22siem-windows%22%20or%20host.name:%20%22siem-suricata%22)%20and%20((process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22))%27)&timerange=(global:(linkTo:!(timeline),timerange:(from:%272019-06-06T06:00:00.000Z%27,kind:absolute,to:%272019-06-07T05:59:59.999Z%27)),timeline:(linkTo:!(global),timerange:(from:%272019-06-06T06:00:00.000Z%27,kind:absolute,to:%272019-06-07T05:59:59.999Z%27)))' ); }); @@ -182,7 +182,7 @@ describe('ml conditional links', () => { loginAndWaitForPageWithoutDateRange(mlHostVariableHostNullKqlQuery); cy.url().should( 'include', - '/app/security/hosts/anomalies?timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))' + '/app/security/hosts/anomalies?timerange=(global:(linkTo:!(timeline),timerange:(from:%272019-06-06T06:00:00.000Z%27,kind:absolute,to:%272019-06-07T05:59:59.999Z%27)),timeline:(linkTo:!(global),timerange:(from:%272019-06-06T06:00:00.000Z%27,kind:absolute,to:%272019-06-07T05:59:59.999Z%27)))' ); }); @@ -190,7 +190,7 @@ describe('ml conditional links', () => { loginAndWaitForPageWithoutDateRange(mlHostVariableHostKqlQuery); cy.url().should( 'include', - '/app/security/hosts/anomalies?query=(language:kuery,query:%27(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)%27)&timerange=(global:(linkTo:!(timeline),timerange:(from:1559800800000,kind:absolute,to:1559887199999)),timeline:(linkTo:!(global),timerange:(from:1559800800000,kind:absolute,to:1559887199999)))' + '/app/security/hosts/anomalies?query=(language:kuery,query:%27(process.name:%20%22conhost.exe%22%20or%20process.name:%20%22sc.exe%22)%27)&timerange=(global:(linkTo:!(timeline),timerange:(from:%272019-06-06T06:00:00.000Z%27,kind:absolute,to:%272019-06-07T05:59:59.999Z%27)),timeline:(linkTo:!(global),timerange:(from:%272019-06-06T06:00:00.000Z%27,kind:absolute,to:%272019-06-07T05:59:59.999Z%27)))' ); }); }); diff --git a/x-pack/plugins/security_solution/cypress/integration/url_compatibility.spec.ts b/x-pack/plugins/security_solution/cypress/integration/url_compatibility.spec.ts index 205a49fc771cf3..5b42897b065e31 100644 --- a/x-pack/plugins/security_solution/cypress/integration/url_compatibility.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/url_compatibility.spec.ts @@ -4,9 +4,19 @@ * you may not use this file except in compliance with the Elastic License. */ -import { loginAndWaitForPage } from '../tasks/login'; +import { loginAndWaitForPage, loginAndWaitForPageWithoutDateRange } from '../tasks/login'; import { DETECTIONS } from '../urls/navigation'; +import { ABSOLUTE_DATE_RANGE } from '../urls/state'; +import { + DATE_PICKER_START_DATE_POPOVER_BUTTON, + DATE_PICKER_END_DATE_POPOVER_BUTTON, +} from '../screens/date_picker'; + +const ABSOLUTE_DATE = { + endTime: '2019-08-01T20:33:29.186Z', + startTime: '2019-08-01T20:03:29.186Z', +}; describe('URL compatibility', () => { it('Redirects to Detection alerts from old Detections URL', () => { @@ -14,4 +24,14 @@ describe('URL compatibility', () => { cy.url().should('include', '/security/detections'); }); + + it('sets the global start and end dates from the url with timestamps', () => { + loginAndWaitForPageWithoutDateRange(ABSOLUTE_DATE_RANGE.urlWithTimestamps); + cy.get(DATE_PICKER_START_DATE_POPOVER_BUTTON).should( + 'have.attr', + 'title', + ABSOLUTE_DATE.startTime + ); + cy.get(DATE_PICKER_END_DATE_POPOVER_BUTTON).should('have.attr', 'title', ABSOLUTE_DATE.endTime); + }); }); diff --git a/x-pack/plugins/security_solution/cypress/integration/url_state.spec.ts b/x-pack/plugins/security_solution/cypress/integration/url_state.spec.ts index 81af9ece9ed451..cdcdde252d6d61 100644 --- a/x-pack/plugins/security_solution/cypress/integration/url_state.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/url_state.spec.ts @@ -42,24 +42,12 @@ import { HOSTS_URL } from '../urls/navigation'; import { ABSOLUTE_DATE_RANGE } from '../urls/state'; const ABSOLUTE_DATE = { - endTime: '1564691609186', - endTimeFormat: '2019-08-01T20:33:29.186Z', - endTimeTimeline: '1564779809186', - endTimeTimelineFormat: '2019-08-02T21:03:29.186Z', - endTimeTimelineTyped: 'Aug 02, 2019 @ 21:03:29.186', - endTimeTyped: 'Aug 01, 2019 @ 14:33:29.186', - newEndTime: '1564693409186', - newEndTimeFormat: '2019-08-01T21:03:29.186Z', + endTime: '2019-08-01T20:33:29.186Z', + endTimeTimeline: '2019-08-02T21:03:29.186Z', newEndTimeTyped: 'Aug 01, 2019 @ 15:03:29.186', - newStartTime: '1564691609186', - newStartTimeFormat: '2019-08-01T20:33:29.186Z', newStartTimeTyped: 'Aug 01, 2019 @ 14:33:29.186', - startTime: '1564689809186', - startTimeFormat: '2019-08-01T20:03:29.186Z', - startTimeTimeline: '1564776209186', - startTimeTimelineFormat: '2019-08-02T20:03:29.186Z', - startTimeTimelineTyped: 'Aug 02, 2019 @ 14:03:29.186', - startTimeTyped: 'Aug 01, 2019 @ 14:03:29.186', + startTime: '2019-08-01T20:03:29.186Z', + startTimeTimeline: '2019-08-02T20:03:29.186Z', }; describe('url state', () => { @@ -68,13 +56,9 @@ describe('url state', () => { cy.get(DATE_PICKER_START_DATE_POPOVER_BUTTON).should( 'have.attr', 'title', - ABSOLUTE_DATE.startTimeFormat - ); - cy.get(DATE_PICKER_END_DATE_POPOVER_BUTTON).should( - 'have.attr', - 'title', - ABSOLUTE_DATE.endTimeFormat + ABSOLUTE_DATE.startTime ); + cy.get(DATE_PICKER_END_DATE_POPOVER_BUTTON).should('have.attr', 'title', ABSOLUTE_DATE.endTime); }); it('sets the url state when start and end date are set', () => { @@ -87,9 +71,11 @@ describe('url state', () => { cy.url().should( 'include', - `(global:(linkTo:!(timeline),timerange:(from:${new Date( + `(global:(linkTo:!(timeline),timerange:(from:%27${new Date( ABSOLUTE_DATE.newStartTimeTyped - ).valueOf()},kind:absolute,to:${new Date(ABSOLUTE_DATE.newEndTimeTyped).valueOf()}))` + ).toISOString()}%27,kind:absolute,to:%27${new Date( + ABSOLUTE_DATE.newEndTimeTyped + ).toISOString()}%27))` ); }); @@ -100,12 +86,12 @@ describe('url state', () => { cy.get(DATE_PICKER_START_DATE_POPOVER_BUTTON_TIMELINE).should( 'have.attr', 'title', - ABSOLUTE_DATE.startTimeFormat + ABSOLUTE_DATE.startTime ); cy.get(DATE_PICKER_END_DATE_POPOVER_BUTTON_TIMELINE).should( 'have.attr', 'title', - ABSOLUTE_DATE.endTimeFormat + ABSOLUTE_DATE.endTime ); }); @@ -114,25 +100,21 @@ describe('url state', () => { cy.get(DATE_PICKER_START_DATE_POPOVER_BUTTON).should( 'have.attr', 'title', - ABSOLUTE_DATE.startTimeFormat - ); - cy.get(DATE_PICKER_END_DATE_POPOVER_BUTTON).should( - 'have.attr', - 'title', - ABSOLUTE_DATE.endTimeFormat + ABSOLUTE_DATE.startTime ); + cy.get(DATE_PICKER_END_DATE_POPOVER_BUTTON).should('have.attr', 'title', ABSOLUTE_DATE.endTime); openTimeline(); cy.get(DATE_PICKER_START_DATE_POPOVER_BUTTON_TIMELINE).should( 'have.attr', 'title', - ABSOLUTE_DATE.startTimeTimelineFormat + ABSOLUTE_DATE.startTimeTimeline ); cy.get(DATE_PICKER_END_DATE_POPOVER_BUTTON_TIMELINE).should( 'have.attr', 'title', - ABSOLUTE_DATE.endTimeTimelineFormat + ABSOLUTE_DATE.endTimeTimeline ); }); @@ -146,9 +128,11 @@ describe('url state', () => { cy.url().should( 'include', - `timeline:(linkTo:!(),timerange:(from:${new Date( + `timeline:(linkTo:!(),timerange:(from:%27${new Date( ABSOLUTE_DATE.newStartTimeTyped - ).valueOf()},kind:absolute,to:${new Date(ABSOLUTE_DATE.newEndTimeTyped).valueOf()}))` + ).toISOString()}%27,kind:absolute,to:%27${new Date( + ABSOLUTE_DATE.newEndTimeTyped + ).toISOString()}%27))` ); }); @@ -180,7 +164,7 @@ describe('url state', () => { cy.get(NETWORK).should( 'have.attr', 'href', - `/app/security/network?query=(language:kuery,query:'source.ip:%20%2210.142.0.9%22%20')&timerange=(global:(linkTo:!(timeline),timerange:(from:1564689809186,kind:absolute,to:1564691609186)),timeline:(linkTo:!(global),timerange:(from:1564689809186,kind:absolute,to:1564691609186)))` + `/app/security/network?query=(language:kuery,query:'source.ip:%20%2210.142.0.9%22%20')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2019-08-01T20:33:29.186Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2019-08-01T20:33:29.186Z')))` ); }); @@ -193,12 +177,12 @@ describe('url state', () => { cy.get(HOSTS).should( 'have.attr', 'href', - `/app/security/hosts?query=(language:kuery,query:'host.name:%20%22siem-kibana%22%20')&timerange=(global:(linkTo:!(timeline),timerange:(from:1564689809186,kind:absolute,to:1577914409186)),timeline:(linkTo:!(global),timerange:(from:1564689809186,kind:absolute,to:1577914409186)))` + `/app/security/hosts?query=(language:kuery,query:'host.name:%20%22siem-kibana%22%20')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2020-01-01T21:33:29.186Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2020-01-01T21:33:29.186Z')))` ); cy.get(NETWORK).should( 'have.attr', 'href', - `/app/security/network?query=(language:kuery,query:'host.name:%20%22siem-kibana%22%20')&timerange=(global:(linkTo:!(timeline),timerange:(from:1564689809186,kind:absolute,to:1577914409186)),timeline:(linkTo:!(global),timerange:(from:1564689809186,kind:absolute,to:1577914409186)))` + `/app/security/network?query=(language:kuery,query:'host.name:%20%22siem-kibana%22%20')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2020-01-01T21:33:29.186Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2020-01-01T21:33:29.186Z')))` ); cy.get(HOSTS_NAMES).first().invoke('text').should('eq', 'siem-kibana'); @@ -209,21 +193,21 @@ describe('url state', () => { cy.get(ANOMALIES_TAB).should( 'have.attr', 'href', - "/app/security/hosts/siem-kibana/anomalies?query=(language:kuery,query:'agent.type:%20%22auditbeat%22%20')&timerange=(global:(linkTo:!(timeline),timerange:(from:1564689809186,kind:absolute,to:1577914409186)),timeline:(linkTo:!(global),timerange:(from:1564689809186,kind:absolute,to:1577914409186)))" + "/app/security/hosts/siem-kibana/anomalies?query=(language:kuery,query:'agent.type:%20%22auditbeat%22%20')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2020-01-01T21:33:29.186Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2020-01-01T21:33:29.186Z')))" ); cy.get(BREADCRUMBS) .eq(1) .should( 'have.attr', 'href', - `/app/security/hosts?query=(language:kuery,query:'agent.type:%20%22auditbeat%22%20')&timerange=(global:(linkTo:!(timeline),timerange:(from:1564689809186,kind:absolute,to:1577914409186)),timeline:(linkTo:!(global),timerange:(from:1564689809186,kind:absolute,to:1577914409186)))` + `/app/security/hosts?query=(language:kuery,query:'agent.type:%20%22auditbeat%22%20')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2020-01-01T21:33:29.186Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2020-01-01T21:33:29.186Z')))` ); cy.get(BREADCRUMBS) .eq(2) .should( 'have.attr', 'href', - `/app/security/hosts/siem-kibana?query=(language:kuery,query:'agent.type:%20%22auditbeat%22%20')&timerange=(global:(linkTo:!(timeline),timerange:(from:1564689809186,kind:absolute,to:1577914409186)),timeline:(linkTo:!(global),timerange:(from:1564689809186,kind:absolute,to:1577914409186)))` + `/app/security/hosts/siem-kibana?query=(language:kuery,query:'agent.type:%20%22auditbeat%22%20')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2020-01-01T21:33:29.186Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2020-01-01T21:33:29.186Z')))` ); }); diff --git a/x-pack/plugins/security_solution/cypress/urls/state.ts b/x-pack/plugins/security_solution/cypress/urls/state.ts index bdd90c21fbedf4..7825be08e38e1a 100644 --- a/x-pack/plugins/security_solution/cypress/urls/state.ts +++ b/x-pack/plugins/security_solution/cypress/urls/state.ts @@ -6,16 +6,18 @@ export const ABSOLUTE_DATE_RANGE = { url: - '/app/security/network/flows/?timerange=(global:(linkTo:!(timeline),timerange:(from:1564689809186,kind:absolute,to:1564691609186)),timeline:(linkTo:!(global),timerange:(from:1564689809186,kind:absolute,to:1564691609186)))', + '/app/security/network/flows/?timerange=(global:(linkTo:!(timeline),timerange:(from:%272019-08-01T20:03:29.186Z%27,kind:absolute,to:%272019-08-01T20:33:29.186Z%27)),timeline:(linkTo:!(global),timerange:(from:%272019-08-01T20:03:29.186Z%27,kind:absolute,to:%272019-08-01T20:33:29.186Z%27)))', + urlWithTimestamps: + '/app/security/network/flows/?timerange=(global:(linkTo:!(timeline),timerange:(from:1564689809186,kind:absolute,to:1564691609186)),timeline:(linkTo:!(global),timerange:(from:1564689809186,kind:absolute,to:1564691609186)))', urlUnlinked: - '/app/security/network/flows/?timerange=(global:(linkTo:!(),timerange:(from:1564689809186,kind:absolute,to:1564691609186)),timeline:(linkTo:!(),timerange:(from:1564776209186,kind:absolute,to:1564779809186)))', - urlKqlNetworkNetwork: `/app/security/network/flows/?query=(language:kuery,query:'source.ip:%20"10.142.0.9"')&timerange=(global:(linkTo:!(timeline),timerange:(from:1564689809186,kind:absolute,to:1564691609186)),timeline:(linkTo:!(global),timerange:(from:1564689809186,kind:absolute,to:1564691609186)))`, - urlKqlNetworkHosts: `/app/security/network/flows/?query=(language:kuery,query:'source.ip:%20"10.142.0.9"')&timerange=(global:(linkTo:!(timeline),timerange:(from:1564689809186,kind:absolute,to:1564691609186)),timeline:(linkTo:!(global),timerange:(from:1564689809186,kind:absolute,to:1564691609186)))`, - urlKqlHostsNetwork: `/app/security/hosts/allHosts?query=(language:kuery,query:'source.ip:%20"10.142.0.9"')&timerange=(global:(linkTo:!(timeline),timerange:(from:1564689809186,kind:absolute,to:1564691609186)),timeline:(linkTo:!(global),timerange:(from:1564689809186,kind:absolute,to:1564691609186)))`, - urlKqlHostsHosts: `/app/security/hosts/allHosts?query=(language:kuery,query:'source.ip:%20"10.142.0.9"')&timerange=(global:(linkTo:!(timeline),timerange:(from:1564689809186,kind:absolute,to:1564691609186)),timeline:(linkTo:!(global),timerange:(from:1564689809186,kind:absolute,to:1564691609186)))`, + '/app/security/network/flows/?timerange=(global:(linkTo:!(),timerange:(from:%272019-08-01T20:03:29.186Z%27,kind:absolute,to:%272019-08-01T20:33:29.186Z%27)),timeline:(linkTo:!(),timerange:(from:%272019-08-02T20:03:29.186Z%27,kind:absolute,to:%272019-08-02T21:03:29.186Z%27)))', + urlKqlNetworkNetwork: `/app/security/network/flows/?query=(language:kuery,query:'source.ip:%20"10.142.0.9"')&timerange=(global:(linkTo:!(timeline),timerange:(from:%272019-08-01T20:03:29.186Z%27,kind:absolute,to:%272019-08-01T20:33:29.186Z%27)),timeline:(linkTo:!(global),timerange:(from:%272019-08-01T20:03:29.186Z%27,kind:absolute,to:%272019-08-01T20:33:29.186Z%27)))`, + urlKqlNetworkHosts: `/app/security/network/flows/?query=(language:kuery,query:'source.ip:%20"10.142.0.9"')&timerange=(global:(linkTo:!(timeline),timerange:(from:%272019-08-01T20:03:29.186Z%27,kind:absolute,to:%272019-08-01T20:33:29.186Z%27)),timeline:(linkTo:!(global),timerange:(from:%272019-08-01T20:03:29.186Z%27,kind:absolute,to:%272019-08-01T20:33:29.186Z%27)))`, + urlKqlHostsNetwork: `/app/security/hosts/allHosts?query=(language:kuery,query:'source.ip:%20"10.142.0.9"')&timerange=(global:(linkTo:!(timeline),timerange:(from:%272019-08-01T20:03:29.186Z%27,kind:absolute,to:%272019-08-01T20:33:29.186Z%27)),timeline:(linkTo:!(global),timerange:(from:%272019-08-01T20:03:29.186Z%27,kind:absolute,to:%272019-08-01T20:33:29.186Z%27)))`, + urlKqlHostsHosts: `/app/security/hosts/allHosts?query=(language:kuery,query:'source.ip:%20"10.142.0.9"')&timerange=(global:(linkTo:!(timeline),timerange:(from:%272019-08-01T20:03:29.186Z%27,kind:absolute,to:%272019-08-01T20:33:29.186Z%27)),timeline:(linkTo:!(global),timerange:(from:%272019-08-01T20:03:29.186Z%27,kind:absolute,to:%272019-08-01T20:33:29.186Z%27)))`, urlHost: - '/app/security/hosts/authentications?timerange=(global:(linkTo:!(timeline),timerange:(from:1564689809186,kind:absolute,to:1564691609186)),timeline:(linkTo:!(global),timerange:(from:1564689809186,kind:absolute,to:1564691609186)))', + '/app/security/hosts/authentications?timerange=(global:(linkTo:!(timeline),timerange:(from:%272019-08-01T20:03:29.186Z%27,kind:absolute,to:%272019-08-01T20:33:29.186Z%27)),timeline:(linkTo:!(global),timerange:(from:%272019-08-01T20:03:29.186Z%27,kind:absolute,to:%272019-08-01T20:33:29.186Z%27)))', urlHostNew: - '/app/security/hosts/authentications?timerange=(global:(linkTo:!(timeline),timerange:(from:1564689809186,kind:absolute,to:1577914409186)),timeline:(linkTo:!(global),timerange:(from:1564689809186,kind:absolute,to:1577914409186)))', + '/app/security/hosts/authentications?timerange=(global:(linkTo:!(timeline),timerange:(from:%272019-08-01T20:03:29.186Z%27,kind:absolute,to:%272020-01-01T21:33:29.186Z%27)),timeline:(linkTo:!(global),timerange:(from:%272019-08-01T20:03:29.186Z%27,kind:absolute,to:%272020-01-01T21:33:29.186Z%27)))', }; diff --git a/x-pack/plugins/security_solution/public/common/components/alerts_viewer/alerts_table.tsx b/x-pack/plugins/security_solution/public/common/components/alerts_viewer/alerts_table.tsx index bf2d8948b72928..841a1ef09ede6c 100644 --- a/x-pack/plugins/security_solution/public/common/components/alerts_viewer/alerts_table.tsx +++ b/x-pack/plugins/security_solution/public/common/components/alerts_viewer/alerts_table.tsx @@ -17,9 +17,9 @@ import * as i18n from './translations'; import { useKibana } from '../../lib/kibana'; export interface OwnProps { - end: number; + end: string; id: string; - start: number; + start: string; } const defaultAlertsFilters: Filter[] = [ @@ -57,8 +57,8 @@ const defaultAlertsFilters: Filter[] = [ interface Props { timelineId: TimelineIdLiteral; - endDate: number; - startDate: number; + endDate: string; + startDate: string; pageFilters?: Filter[]; } diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx index 38ca1176d1700c..674eb3325efc2c 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx @@ -15,29 +15,36 @@ import { mockEventViewerResponse } from './mock'; import { StatefulEventsViewer } from '.'; import { defaultHeaders } from './default_headers'; import { useFetchIndexPatterns } from '../../../detections/containers/detection_engine/rules/fetch_index_patterns'; -import { mockBrowserFields } from '../../containers/source/mock'; +import { mockBrowserFields, mockDocValueFields } from '../../containers/source/mock'; import { eventsDefaultModel } from './default_model'; import { useMountAppended } from '../../utils/use_mount_appended'; +jest.mock('../../components/url_state/normalize_time_range.ts'); + const mockUseFetchIndexPatterns: jest.Mock = useFetchIndexPatterns as jest.Mock; jest.mock('../../../detections/containers/detection_engine/rules/fetch_index_patterns'); -mockUseFetchIndexPatterns.mockImplementation(() => [ - { - browserFields: mockBrowserFields, - indexPatterns: mockIndexPattern, - }, -]); const mockUseResizeObserver: jest.Mock = useResizeObserver as jest.Mock; jest.mock('use-resize-observer/polyfilled'); mockUseResizeObserver.mockImplementation(() => ({})); -const from = 1566943856794; -const to = 1566857456791; +const from = '2019-08-26T22:10:56.791Z'; +const to = '2019-08-27T22:10:56.794Z'; describe('EventsViewer', () => { const mount = useMountAppended(); + beforeEach(() => { + mockUseFetchIndexPatterns.mockImplementation(() => [ + { + browserFields: mockBrowserFields, + indexPatterns: mockIndexPattern, + docValueFields: mockDocValueFields, + isLoading: false, + }, + ]); + }); + test('it renders the "Showing..." subtitle with the expected event count', async () => { const wrapper = mount( @@ -60,6 +67,93 @@ describe('EventsViewer', () => { ); }); + test('it does NOT render fetch index pattern is loading', async () => { + mockUseFetchIndexPatterns.mockImplementation(() => [ + { + browserFields: mockBrowserFields, + indexPatterns: mockIndexPattern, + docValueFields: mockDocValueFields, + isLoading: true, + }, + ]); + + const wrapper = mount( + + + + + + ); + + await wait(); + wrapper.update(); + + expect(wrapper.find(`[data-test-subj="header-section-subtitle"]`).first().exists()).toBe(false); + }); + + test('it does NOT render when start is empty', async () => { + mockUseFetchIndexPatterns.mockImplementation(() => [ + { + browserFields: mockBrowserFields, + indexPatterns: mockIndexPattern, + docValueFields: mockDocValueFields, + isLoading: true, + }, + ]); + + const wrapper = mount( + + + + + + ); + + await wait(); + wrapper.update(); + + expect(wrapper.find(`[data-test-subj="header-section-subtitle"]`).first().exists()).toBe(false); + }); + + test('it does NOT render when end is empty', async () => { + mockUseFetchIndexPatterns.mockImplementation(() => [ + { + browserFields: mockBrowserFields, + indexPatterns: mockIndexPattern, + docValueFields: mockDocValueFields, + isLoading: true, + }, + ]); + + const wrapper = mount( + + + + + + ); + + await wait(); + wrapper.update(); + + expect(wrapper.find(`[data-test-subj="header-section-subtitle"]`).first().exists()).toBe(false); + }); + test('it renders the Fields Browser as a settings gear', async () => { const wrapper = mount( diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx index a81c5facb07182..5e0d5a6e9b0993 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx @@ -10,7 +10,7 @@ import React, { useEffect, useMemo, useState } from 'react'; import styled from 'styled-components'; import deepEqual from 'fast-deep-equal'; -import { BrowserFields } from '../../containers/source'; +import { BrowserFields, DocValueFields } from '../../containers/source'; import { TimelineQuery } from '../../../timelines/containers'; import { Direction } from '../../../graphql/types'; import { useKibana } from '../../lib/kibana'; @@ -51,19 +51,21 @@ interface Props { columns: ColumnHeaderOptions[]; dataProviders: DataProvider[]; deletedEventIds: Readonly; - end: number; + docValueFields: DocValueFields[]; + end: string; filters: Filter[]; headerFilterGroup?: React.ReactNode; height?: number; id: string; indexPattern: IIndexPattern; isLive: boolean; + isLoadingIndexPattern: boolean; itemsPerPage: number; itemsPerPageOptions: number[]; kqlMode: KqlMode; onChangeItemsPerPage: OnChangeItemsPerPage; query: Query; - start: number; + start: string; sort: Sort; toggleColumn: (column: ColumnHeaderOptions) => void; utilityBar?: (refetch: inputsModel.Refetch, totalCount: number) => React.ReactNode; @@ -76,6 +78,7 @@ const EventsViewerComponent: React.FC = ({ columns, dataProviders, deletedEventIds, + docValueFields, end, filters, headerFilterGroup, @@ -83,6 +86,7 @@ const EventsViewerComponent: React.FC = ({ id, indexPattern, isLive, + isLoadingIndexPattern, itemsPerPage, itemsPerPageOptions, kqlMode, @@ -122,6 +126,17 @@ const EventsViewerComponent: React.FC = ({ end, isEventViewer: true, }); + + const canQueryTimeline = useMemo( + () => + combinedQueries != null && + isLoadingIndexPattern != null && + !isLoadingIndexPattern && + !isEmpty(start) && + !isEmpty(end), + [isLoadingIndexPattern, combinedQueries, start, end] + ); + const fields = useMemo( () => union( @@ -140,16 +155,19 @@ const EventsViewerComponent: React.FC = ({ return ( - {combinedQueries != null ? ( + {canQueryTimeline ? ( {({ events, @@ -187,6 +205,7 @@ const EventsViewerComponent: React.FC = ({ !deletedEventIds.includes(e._id))} + docValueFields={docValueFields} id={id} isEventViewer={true} height={height} @@ -232,6 +251,7 @@ export const EventsViewer = React.memo( (prevProps, nextProps) => deepEqual(prevProps.browserFields, nextProps.browserFields) && prevProps.columns === nextProps.columns && + deepEqual(prevProps.docValueFields, nextProps.docValueFields) && prevProps.dataProviders === nextProps.dataProviders && prevProps.deletedEventIds === nextProps.deletedEventIds && prevProps.end === nextProps.end && diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.test.tsx index a5f4dc0c5ed6fa..1f820c0c748b61 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.test.tsx @@ -18,6 +18,8 @@ import { useFetchIndexPatterns } from '../../../detections/containers/detection_ import { mockBrowserFields } from '../../containers/source/mock'; import { eventsDefaultModel } from './default_model'; +jest.mock('../../components/url_state/normalize_time_range.ts'); + const mockUseFetchIndexPatterns: jest.Mock = useFetchIndexPatterns as jest.Mock; jest.mock('../../../detections/containers/detection_engine/rules/fetch_index_patterns'); mockUseFetchIndexPatterns.mockImplementation(() => [ @@ -31,8 +33,8 @@ const mockUseResizeObserver: jest.Mock = useResizeObserver as jest.Mock; jest.mock('use-resize-observer/polyfilled'); mockUseResizeObserver.mockImplementation(() => ({})); -const from = 1566943856794; -const to = 1566857456791; +const from = '2019-08-27T22:10:56.794Z'; +const to = '2019-08-26T22:10:56.791Z'; describe('StatefulEventsViewer', () => { const mount = useMountAppended(); diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx index 637f1a48143a9f..6c610a084e7f29 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/index.tsx @@ -27,9 +27,9 @@ import { InspectButtonContainer } from '../inspect'; export interface OwnProps { defaultIndices?: string[]; defaultModel: SubsetTimelineModel; - end: number; + end: string; id: string; - start: number; + start: string; headerFilterGroup?: React.ReactNode; pageFilters?: Filter[]; utilityBar?: (refetch: inputsModel.Refetch, totalCount: number) => React.ReactNode; @@ -65,9 +65,9 @@ const StatefulEventsViewerComponent: React.FC = ({ // If truthy, the graph viewer (Resolver) is showing graphEventId, }) => { - const [{ browserFields, indexPatterns }] = useFetchIndexPatterns( - defaultIndices ?? useUiSetting(DEFAULT_INDEX_KEY) - ); + const [ + { docValueFields, browserFields, indexPatterns, isLoading: isLoadingIndexPattern }, + ] = useFetchIndexPatterns(defaultIndices ?? useUiSetting(DEFAULT_INDEX_KEY)); useEffect(() => { if (createTimeline != null) { @@ -120,10 +120,12 @@ const StatefulEventsViewerComponent: React.FC = ({ { const mockMatrixOverTimeHistogramProps = { defaultIndex: ['defaultIndex'], defaultStackByOption: { text: 'text', value: 'value' }, - endDate: new Date('2019-07-18T20:00:00.000Z').valueOf(), + endDate: '2019-07-18T20:00:00.000Z', errorMessage: 'error', histogramType: HistogramType.alerts, id: 'mockId', @@ -64,7 +64,7 @@ describe('Matrix Histogram Component', () => { sourceId: 'default', stackByField: 'mockStackByField', stackByOptions: [{ text: 'text', value: 'value' }], - startDate: new Date('2019-07-18T19:00: 00.000Z').valueOf(), + startDate: '2019-07-18T19:00: 00.000Z', subtitle: 'mockSubtitle', totalCount: -1, title: 'mockTitle', diff --git a/x-pack/plugins/security_solution/public/common/components/matrix_histogram/index.tsx b/x-pack/plugins/security_solution/public/common/components/matrix_histogram/index.tsx index 16fe2a6669ff0f..fa512ad1ed80bf 100644 --- a/x-pack/plugins/security_solution/public/common/components/matrix_histogram/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/matrix_histogram/index.tsx @@ -115,8 +115,8 @@ export const MatrixHistogramComponent: React.FC< const [min, max] = x; dispatchSetAbsoluteRangeDatePicker({ id: setAbsoluteRangeDatePickerTarget, - from: min, - to: max, + from: new Date(min).toISOString(), + to: new Date(max).toISOString(), }); }, yTickFormatter, diff --git a/x-pack/plugins/security_solution/public/common/components/matrix_histogram/types.ts b/x-pack/plugins/security_solution/public/common/components/matrix_histogram/types.ts index ff0816758cb0c4..a859b0dd392310 100644 --- a/x-pack/plugins/security_solution/public/common/components/matrix_histogram/types.ts +++ b/x-pack/plugins/security_solution/public/common/components/matrix_histogram/types.ts @@ -44,8 +44,8 @@ interface MatrixHistogramBasicProps { defaultStackByOption: MatrixHistogramOption; dispatchSetAbsoluteRangeDatePicker: ActionCreator<{ id: InputsModelId; - from: number; - to: number; + from: string; + to: string; }>; endDate: GlobalTimeArgs['to']; headerChildren?: React.ReactNode; @@ -63,17 +63,17 @@ interface MatrixHistogramBasicProps { } export interface MatrixHistogramQueryProps { - endDate: number; + endDate: string; errorMessage: string; filterQuery?: ESQuery | string | undefined; setAbsoluteRangeDatePicker?: ActionCreator<{ id: InputsModelId; - from: number; - to: number; + from: string; + to: string; }>; setAbsoluteRangeDatePickerTarget?: InputsModelId; stackByField: string; - startDate: number; + startDate: string; indexToAdd?: string[] | null; isInspected: boolean; histogramType: HistogramType; diff --git a/x-pack/plugins/security_solution/public/common/components/matrix_histogram/utils.test.ts b/x-pack/plugins/security_solution/public/common/components/matrix_histogram/utils.test.ts index 9e3ddcc014c61b..7a3f44d3ea7296 100644 --- a/x-pack/plugins/security_solution/public/common/components/matrix_histogram/utils.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/matrix_histogram/utils.test.ts @@ -22,8 +22,8 @@ describe('utils', () => { let configs: BarchartConfigs; beforeAll(() => { configs = getBarchartConfigs({ - from: 0, - to: 0, + from: '2020-07-07T08:20:18.966Z', + to: '2020-07-08T08:20:18.966Z', onBrushEnd: jest.fn() as UpdateDateRange, }); }); @@ -53,8 +53,8 @@ describe('utils', () => { beforeAll(() => { configs = getBarchartConfigs({ chartHeight: mockChartHeight, - from: 0, - to: 0, + from: '2020-07-07T08:20:18.966Z', + to: '2020-07-08T08:20:18.966Z', onBrushEnd: jest.fn() as UpdateDateRange, yTickFormatter: mockYTickFormatter, showLegend: false, diff --git a/x-pack/plugins/security_solution/public/common/components/matrix_histogram/utils.ts b/x-pack/plugins/security_solution/public/common/components/matrix_histogram/utils.ts index 45e9c54b2eff87..9474929d35a517 100644 --- a/x-pack/plugins/security_solution/public/common/components/matrix_histogram/utils.ts +++ b/x-pack/plugins/security_solution/public/common/components/matrix_histogram/utils.ts @@ -13,9 +13,9 @@ import { histogramDateTimeFormatter } from '../utils'; interface GetBarchartConfigsProps { chartHeight?: number; - from: number; + from: string; legendPosition?: Position; - to: number; + to: string; onBrushEnd: UpdateDateRange; yTickFormatter?: (value: number) => string; showLegend?: boolean; diff --git a/x-pack/plugins/security_solution/public/common/components/ml/anomaly/anomaly_table_provider.tsx b/x-pack/plugins/security_solution/public/common/components/ml/anomaly/anomaly_table_provider.tsx index 6ccc41546e5587..66e70ddc2e14f8 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/anomaly/anomaly_table_provider.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/anomaly/anomaly_table_provider.tsx @@ -15,8 +15,8 @@ interface ChildrenArgs { interface Props { influencers?: InfluencerInput[]; - startDate: number; - endDate: number; + startDate: string; + endDate: string; criteriaFields?: CriteriaFields[]; children: (args: ChildrenArgs) => React.ReactNode; skip: boolean; diff --git a/x-pack/plugins/security_solution/public/common/components/ml/anomaly/use_anomalies_table_data.ts b/x-pack/plugins/security_solution/public/common/components/ml/anomaly/use_anomalies_table_data.ts index 8568c7e6b55757..a6bbdee79cf04f 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/anomaly/use_anomalies_table_data.ts +++ b/x-pack/plugins/security_solution/public/common/components/ml/anomaly/use_anomalies_table_data.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { useState, useEffect } from 'react'; +import { useState, useEffect, useMemo } from 'react'; import { DEFAULT_ANOMALY_SCORE } from '../../../../../common/constants'; import { anomaliesTableData } from '../api/anomalies_table_data'; @@ -19,8 +19,8 @@ import { useTimeZone, useUiSetting$ } from '../../../lib/kibana'; interface Args { influencers?: InfluencerInput[]; - endDate: number; - startDate: number; + endDate: string; + startDate: string; threshold?: number; skip?: boolean; criteriaFields?: CriteriaFields[]; @@ -67,6 +67,8 @@ export const useAnomaliesTableData = ({ const [anomalyScore] = useUiSetting$(DEFAULT_ANOMALY_SCORE); const siemJobIds = siemJobs.filter((job) => job.isInstalled).map((job) => job.id); + const startDateMs = useMemo(() => new Date(startDate).getTime(), [startDate]); + const endDateMs = useMemo(() => new Date(endDate).getTime(), [endDate]); useEffect(() => { let isSubscribed = true; @@ -116,7 +118,7 @@ export const useAnomaliesTableData = ({ } } - fetchAnomaliesTableData(influencers, criteriaFields, startDate, endDate); + fetchAnomaliesTableData(influencers, criteriaFields, startDateMs, endDateMs); return () => { isSubscribed = false; abortCtrl.abort(); diff --git a/x-pack/plugins/security_solution/public/common/components/ml/links/create_explorer_link.test.ts b/x-pack/plugins/security_solution/public/common/components/ml/links/create_explorer_link.test.ts index 4a25f82a94a618..30d0673192af85 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/links/create_explorer_link.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/ml/links/create_explorer_link.test.ts @@ -18,8 +18,8 @@ describe('create_explorer_link', () => { test('it returns expected link', () => { const entities = createExplorerLink( anomalies.anomalies[0], - new Date('1970').valueOf(), - new Date('3000').valueOf() + new Date('1970').toISOString(), + new Date('3000').toISOString() ); expect(entities).toEqual( "#/explorer?_g=(ml:(jobIds:!(job-1)),refreshInterval:(display:Off,pause:!f,value:0),time:(from:'1970-01-01T00:00:00.000Z',mode:absolute,to:'3000-01-01T00:00:00.000Z'))&_a=(mlExplorerFilter:(),mlExplorerSwimlane:(),mlSelectLimit:(display:'10',val:10),mlShowCharts:!t)" diff --git a/x-pack/plugins/security_solution/public/common/components/ml/links/create_explorer_link.tsx b/x-pack/plugins/security_solution/public/common/components/ml/links/create_explorer_link.tsx index e00f53a08a9184..468bc962453f68 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/links/create_explorer_link.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/links/create_explorer_link.tsx @@ -11,8 +11,8 @@ import { useKibana } from '../../../lib/kibana'; interface ExplorerLinkProps { score: Anomaly; - startDate: number; - endDate: number; + startDate: string; + endDate: string; linkName: React.ReactNode; } @@ -35,7 +35,7 @@ export const ExplorerLink: React.FC = ({ ); }; -export const createExplorerLink = (score: Anomaly, startDate: number, endDate: number): string => { +export const createExplorerLink = (score: Anomaly, startDate: string, endDate: string): string => { const startDateIso = new Date(startDate).toISOString(); const endDateIso = new Date(endDate).toISOString(); diff --git a/x-pack/plugins/security_solution/public/common/components/ml/score/__snapshots__/anomaly_score.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/ml/score/__snapshots__/anomaly_score.test.tsx.snap index 6694cec53987b2..0abb94f6e92ffa 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/score/__snapshots__/anomaly_score.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/common/components/ml/score/__snapshots__/anomaly_score.test.tsx.snap @@ -127,7 +127,7 @@ exports[`anomaly_scores renders correctly against snapshot 1`] = ` grow={false} > , diff --git a/x-pack/plugins/security_solution/public/common/components/ml/score/__snapshots__/anomaly_scores.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/ml/score/__snapshots__/anomaly_scores.test.tsx.snap index de9ae94c4d95ee..b9e4a76363a40d 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/score/__snapshots__/anomaly_scores.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/common/components/ml/score/__snapshots__/anomaly_scores.test.tsx.snap @@ -7,7 +7,7 @@ exports[`anomaly_scores renders correctly against snapshot 1`] = ` responsive={false} > diff --git a/x-pack/plugins/security_solution/public/common/components/ml/score/__snapshots__/create_descriptions_list.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/ml/score/__snapshots__/create_descriptions_list.test.tsx.snap index 2e771f9f045b88..5d052ef028e0f3 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/score/__snapshots__/create_descriptions_list.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/common/components/ml/score/__snapshots__/create_descriptions_list.test.tsx.snap @@ -44,7 +44,7 @@ exports[`create_description_list renders correctly against snapshot 1`] = ` grow={false} > diff --git a/x-pack/plugins/security_solution/public/common/components/ml/score/anomaly_score.test.tsx b/x-pack/plugins/security_solution/public/common/components/ml/score/anomaly_score.test.tsx index b172c22a9ed4e6..f7fa0ac0a8be15 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/score/anomaly_score.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/score/anomaly_score.test.tsx @@ -13,7 +13,9 @@ import { TestProviders } from '../../../mock/test_providers'; import { useMountAppended } from '../../../utils/use_mount_appended'; import { Anomalies } from '../types'; -const endDate: number = new Date('3000-01-01T00:00:00.000Z').valueOf(); +const startDate: string = '2020-07-07T08:20:18.966Z'; +const endDate: string = '3000-01-01T00:00:00.000Z'; + const narrowDateRange = jest.fn(); describe('anomaly_scores', () => { @@ -28,7 +30,7 @@ describe('anomaly_scores', () => { const wrapper = shallow( { { { @@ -29,7 +30,7 @@ describe('anomaly_scores', () => { const wrapper = shallow( { { { { { { { diff --git a/x-pack/plugins/security_solution/public/common/components/ml/score/create_descriptions_list.test.tsx b/x-pack/plugins/security_solution/public/common/components/ml/score/create_descriptions_list.test.tsx index 7c8900bf77d95b..e9dd5f922e26a5 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/score/create_descriptions_list.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/score/create_descriptions_list.test.tsx @@ -13,7 +13,8 @@ import { Anomaly } from '../types'; jest.mock('../../../lib/kibana'); -const endDate: number = new Date('3000-01-01T00:00:00.000Z').valueOf(); +const startDate: string = '2020-07-07T08:20:18.966Z'; +const endDate: string = '3000-01-01T00:00:00.000Z'; describe('create_description_list', () => { let narrowDateRange = jest.fn(); @@ -27,7 +28,7 @@ describe('create_description_list', () => { { { { { test('converts a second interval to plus or minus (+/-) one hour', () => { const expected: FromTo = { - from: new Date('2019-06-25T04:31:59.345Z').valueOf(), - to: new Date('2019-06-25T06:31:59.345Z').valueOf(), + from: '2019-06-25T04:31:59.345Z', + to: '2019-06-25T06:31:59.345Z', }; anomalies.anomalies[0].time = new Date('2019-06-25T05:31:59.345Z').valueOf(); expect(scoreIntervalToDateTime(anomalies.anomalies[0], 'second')).toEqual(expected); @@ -26,8 +26,8 @@ describe('score_interval_to_datetime', () => { test('converts a minute interval to plus or minus (+/-) one hour', () => { const expected: FromTo = { - from: new Date('2019-06-25T04:31:59.345Z').valueOf(), - to: new Date('2019-06-25T06:31:59.345Z').valueOf(), + from: '2019-06-25T04:31:59.345Z', + to: '2019-06-25T06:31:59.345Z', }; anomalies.anomalies[0].time = new Date('2019-06-25T05:31:59.345Z').valueOf(); expect(scoreIntervalToDateTime(anomalies.anomalies[0], 'minute')).toEqual(expected); @@ -35,8 +35,8 @@ describe('score_interval_to_datetime', () => { test('converts a hour interval to plus or minus (+/-) one hour', () => { const expected: FromTo = { - from: new Date('2019-06-25T04:31:59.345Z').valueOf(), - to: new Date('2019-06-25T06:31:59.345Z').valueOf(), + from: '2019-06-25T04:31:59.345Z', + to: '2019-06-25T06:31:59.345Z', }; anomalies.anomalies[0].time = new Date('2019-06-25T05:31:59.345Z').valueOf(); expect(scoreIntervalToDateTime(anomalies.anomalies[0], 'hour')).toEqual(expected); @@ -44,8 +44,8 @@ describe('score_interval_to_datetime', () => { test('converts a day interval to plus or minus (+/-) one day', () => { const expected: FromTo = { - from: new Date('2019-06-24T05:31:59.345Z').valueOf(), - to: new Date('2019-06-26T05:31:59.345Z').valueOf(), + from: '2019-06-24T05:31:59.345Z', + to: '2019-06-26T05:31:59.345Z', }; anomalies.anomalies[0].time = new Date('2019-06-25T05:31:59.345Z').valueOf(); expect(scoreIntervalToDateTime(anomalies.anomalies[0], 'day')).toEqual(expected); diff --git a/x-pack/plugins/security_solution/public/common/components/ml/score/score_interval_to_datetime.ts b/x-pack/plugins/security_solution/public/common/components/ml/score/score_interval_to_datetime.ts index b1257676a64b25..69b5be9272a385 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/score/score_interval_to_datetime.ts +++ b/x-pack/plugins/security_solution/public/common/components/ml/score/score_interval_to_datetime.ts @@ -8,21 +8,21 @@ import moment from 'moment'; import { Anomaly } from '../types'; export interface FromTo { - from: number; - to: number; + from: string; + to: string; } export const scoreIntervalToDateTime = (score: Anomaly, interval: string): FromTo => { if (interval === 'second' || interval === 'minute' || interval === 'hour') { return { - from: moment(score.time).subtract(1, 'hour').valueOf(), - to: moment(score.time).add(1, 'hour').valueOf(), + from: moment(score.time).subtract(1, 'hour').toISOString(), + to: moment(score.time).add(1, 'hour').toISOString(), }; } else { // default should be a day return { - from: moment(score.time).subtract(1, 'day').valueOf(), - to: moment(score.time).add(1, 'day').valueOf(), + from: moment(score.time).subtract(1, 'day').toISOString(), + to: moment(score.time).add(1, 'day').toISOString(), }; } }; diff --git a/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_host_table_columns.test.tsx b/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_host_table_columns.test.tsx index 93b22460d4ed77..b90946c534f3ac 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_host_table_columns.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_host_table_columns.test.tsx @@ -13,8 +13,8 @@ import { TestProviders } from '../../../mock'; import React from 'react'; import { useMountAppended } from '../../../utils/use_mount_appended'; -const startDate = new Date(2001).valueOf(); -const endDate = new Date(3000).valueOf(); +const startDate = new Date(2001).toISOString(); +const endDate = new Date(3000).toISOString(); const interval = 'days'; const narrowDateRange = jest.fn(); diff --git a/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_host_table_columns.tsx b/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_host_table_columns.tsx index fc89189bf4f465..b72da55128f994 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_host_table_columns.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_host_table_columns.tsx @@ -24,8 +24,8 @@ import { escapeDataProviderId } from '../../drag_and_drop/helpers'; import { FormattedRelativePreferenceDate } from '../../formatted_date'; export const getAnomaliesHostTableColumns = ( - startDate: number, - endDate: number, + startDate: string, + endDate: string, interval: string, narrowDateRange: NarrowDateRange ): [ @@ -132,8 +132,8 @@ export const getAnomaliesHostTableColumns = ( export const getAnomaliesHostTableColumnsCurated = ( pageType: HostsType, - startDate: number, - endDate: number, + startDate: string, + endDate: string, interval: string, narrowDateRange: NarrowDateRange ) => { diff --git a/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_network_table_columns.test.tsx b/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_network_table_columns.test.tsx index b113c692c535a2..79277c46e1c9d0 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_network_table_columns.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_network_table_columns.test.tsx @@ -13,8 +13,8 @@ import React from 'react'; import { TestProviders } from '../../../mock'; import { useMountAppended } from '../../../utils/use_mount_appended'; -const startDate = new Date(2001).valueOf(); -const endDate = new Date(3000).valueOf(); +const startDate = new Date(2001).toISOString(); +const endDate = new Date(3000).toISOString(); describe('get_anomalies_network_table_columns', () => { const mount = useMountAppended(); diff --git a/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_network_table_columns.tsx b/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_network_table_columns.tsx index ce4269afbe5b2a..52b26a20a8f644 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_network_table_columns.tsx +++ b/x-pack/plugins/security_solution/public/common/components/ml/tables/get_anomalies_network_table_columns.tsx @@ -26,8 +26,8 @@ import { escapeDataProviderId } from '../../drag_and_drop/helpers'; import { FlowTarget } from '../../../../graphql/types'; export const getAnomaliesNetworkTableColumns = ( - startDate: number, - endDate: number, + startDate: string, + endDate: string, flowTarget?: FlowTarget ): [ Columns, @@ -127,8 +127,8 @@ export const getAnomaliesNetworkTableColumns = ( export const getAnomaliesNetworkTableColumnsCurated = ( pageType: NetworkType, - startDate: number, - endDate: number, + startDate: string, + endDate: string, flowTarget?: FlowTarget ) => { const columns = getAnomaliesNetworkTableColumns(startDate, endDate, flowTarget); diff --git a/x-pack/plugins/security_solution/public/common/components/ml/tables/host_equality.test.ts b/x-pack/plugins/security_solution/public/common/components/ml/tables/host_equality.test.ts index 89b87f95e5159d..eaaf5a9aedcdb9 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/tables/host_equality.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/ml/tables/host_equality.test.ts @@ -11,15 +11,15 @@ import { HostsType } from '../../../../hosts/store/model'; describe('host_equality', () => { test('it returns true if start and end date are equal', () => { const prev: AnomaliesHostTableProps = { - startDate: new Date('2000').valueOf(), - endDate: new Date('2000').valueOf(), + startDate: new Date('2000').toISOString(), + endDate: new Date('2000').toISOString(), narrowDateRange: jest.fn(), skip: false, type: HostsType.details, }; const next: AnomaliesHostTableProps = { - startDate: new Date('2000').valueOf(), - endDate: new Date('2000').valueOf(), + startDate: new Date('2000').toISOString(), + endDate: new Date('2000').toISOString(), narrowDateRange: jest.fn(), skip: false, type: HostsType.details, @@ -30,15 +30,15 @@ describe('host_equality', () => { test('it returns false if starts are not equal', () => { const prev: AnomaliesHostTableProps = { - startDate: new Date('2001').valueOf(), - endDate: new Date('2000').valueOf(), + startDate: new Date('2001').toISOString(), + endDate: new Date('2000').toISOString(), narrowDateRange: jest.fn(), skip: false, type: HostsType.details, }; const next: AnomaliesHostTableProps = { - startDate: new Date('2000').valueOf(), - endDate: new Date('2000').valueOf(), + startDate: new Date('2000').toISOString(), + endDate: new Date('2000').toISOString(), narrowDateRange: jest.fn(), skip: false, type: HostsType.details, @@ -49,15 +49,15 @@ describe('host_equality', () => { test('it returns false if starts are not equal for next', () => { const prev: AnomaliesHostTableProps = { - startDate: new Date('2000').valueOf(), - endDate: new Date('2000').valueOf(), + startDate: new Date('2000').toISOString(), + endDate: new Date('2000').toISOString(), narrowDateRange: jest.fn(), skip: false, type: HostsType.details, }; const next: AnomaliesHostTableProps = { - startDate: new Date('2001').valueOf(), - endDate: new Date('2000').valueOf(), + startDate: new Date('2001').toISOString(), + endDate: new Date('2000').toISOString(), narrowDateRange: jest.fn(), skip: false, type: HostsType.details, @@ -68,15 +68,15 @@ describe('host_equality', () => { test('it returns false if ends are not equal', () => { const prev: AnomaliesHostTableProps = { - startDate: new Date('2000').valueOf(), - endDate: new Date('2001').valueOf(), + startDate: new Date('2000').toISOString(), + endDate: new Date('2001').toISOString(), narrowDateRange: jest.fn(), skip: false, type: HostsType.details, }; const next: AnomaliesHostTableProps = { - startDate: new Date('2000').valueOf(), - endDate: new Date('2000').valueOf(), + startDate: new Date('2000').toISOString(), + endDate: new Date('2000').toISOString(), narrowDateRange: jest.fn(), skip: false, type: HostsType.details, @@ -87,15 +87,15 @@ describe('host_equality', () => { test('it returns false if ends are not equal for next', () => { const prev: AnomaliesHostTableProps = { - startDate: new Date('2000').valueOf(), - endDate: new Date('2000').valueOf(), + startDate: new Date('2000').toISOString(), + endDate: new Date('2000').toISOString(), narrowDateRange: jest.fn(), skip: false, type: HostsType.details, }; const next: AnomaliesHostTableProps = { - startDate: new Date('2000').valueOf(), - endDate: new Date('2001').valueOf(), + startDate: new Date('2000').toISOString(), + endDate: new Date('2001').toISOString(), narrowDateRange: jest.fn(), skip: false, type: HostsType.details, @@ -106,15 +106,15 @@ describe('host_equality', () => { test('it returns false if skip is not equal', () => { const prev: AnomaliesHostTableProps = { - startDate: new Date('2000').valueOf(), - endDate: new Date('2000').valueOf(), + startDate: new Date('2000').toISOString(), + endDate: new Date('2000').toISOString(), narrowDateRange: jest.fn(), skip: true, type: HostsType.details, }; const next: AnomaliesHostTableProps = { - startDate: new Date('2000').valueOf(), - endDate: new Date('2000').valueOf(), + startDate: new Date('2000').toISOString(), + endDate: new Date('2000').toISOString(), narrowDateRange: jest.fn(), skip: false, type: HostsType.details, diff --git a/x-pack/plugins/security_solution/public/common/components/ml/tables/network_equality.test.ts b/x-pack/plugins/security_solution/public/common/components/ml/tables/network_equality.test.ts index 8b3e30c3290314..3819e9d0e4b3fe 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/tables/network_equality.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/ml/tables/network_equality.test.ts @@ -12,15 +12,15 @@ import { FlowTarget } from '../../../../graphql/types'; describe('network_equality', () => { test('it returns true if start and end date are equal', () => { const prev: AnomaliesNetworkTableProps = { - startDate: new Date('2000').valueOf(), - endDate: new Date('2000').valueOf(), + startDate: new Date('2000').toISOString(), + endDate: new Date('2000').toISOString(), narrowDateRange: jest.fn(), skip: false, type: NetworkType.details, }; const next: AnomaliesNetworkTableProps = { - startDate: new Date('2000').valueOf(), - endDate: new Date('2000').valueOf(), + startDate: new Date('2000').toISOString(), + endDate: new Date('2000').toISOString(), narrowDateRange: jest.fn(), skip: false, type: NetworkType.details, @@ -31,15 +31,15 @@ describe('network_equality', () => { test('it returns false if starts are not equal', () => { const prev: AnomaliesNetworkTableProps = { - startDate: new Date('2001').valueOf(), - endDate: new Date('2000').valueOf(), + startDate: new Date('2001').toISOString(), + endDate: new Date('2000').toISOString(), narrowDateRange: jest.fn(), skip: false, type: NetworkType.details, }; const next: AnomaliesNetworkTableProps = { - startDate: new Date('2000').valueOf(), - endDate: new Date('2000').valueOf(), + startDate: new Date('2000').toISOString(), + endDate: new Date('2000').toISOString(), narrowDateRange: jest.fn(), skip: false, type: NetworkType.details, @@ -50,15 +50,15 @@ describe('network_equality', () => { test('it returns false if starts are not equal for next', () => { const prev: AnomaliesNetworkTableProps = { - startDate: new Date('2000').valueOf(), - endDate: new Date('2000').valueOf(), + startDate: new Date('2000').toISOString(), + endDate: new Date('2000').toISOString(), narrowDateRange: jest.fn(), skip: false, type: NetworkType.details, }; const next: AnomaliesNetworkTableProps = { - startDate: new Date('2001').valueOf(), - endDate: new Date('2000').valueOf(), + startDate: new Date('2001').toISOString(), + endDate: new Date('2000').toISOString(), narrowDateRange: jest.fn(), skip: false, type: NetworkType.details, @@ -69,15 +69,15 @@ describe('network_equality', () => { test('it returns false if ends are not equal', () => { const prev: AnomaliesNetworkTableProps = { - startDate: new Date('2000').valueOf(), - endDate: new Date('2001').valueOf(), + startDate: new Date('2000').toISOString(), + endDate: new Date('2001').toISOString(), narrowDateRange: jest.fn(), skip: false, type: NetworkType.details, }; const next: AnomaliesNetworkTableProps = { - startDate: new Date('2000').valueOf(), - endDate: new Date('2000').valueOf(), + startDate: new Date('2000').toISOString(), + endDate: new Date('2000').toISOString(), narrowDateRange: jest.fn(), skip: false, type: NetworkType.details, @@ -88,15 +88,15 @@ describe('network_equality', () => { test('it returns false if ends are not equal for next', () => { const prev: AnomaliesNetworkTableProps = { - startDate: new Date('2000').valueOf(), - endDate: new Date('2000').valueOf(), + startDate: new Date('2000').toISOString(), + endDate: new Date('2000').toISOString(), narrowDateRange: jest.fn(), skip: false, type: NetworkType.details, }; const next: AnomaliesNetworkTableProps = { - startDate: new Date('2000').valueOf(), - endDate: new Date('2001').valueOf(), + startDate: new Date('2000').toISOString(), + endDate: new Date('2001').toISOString(), narrowDateRange: jest.fn(), skip: false, type: NetworkType.details, @@ -107,15 +107,15 @@ describe('network_equality', () => { test('it returns false if skip is not equal', () => { const prev: AnomaliesNetworkTableProps = { - startDate: new Date('2000').valueOf(), - endDate: new Date('2000').valueOf(), + startDate: new Date('2000').toISOString(), + endDate: new Date('2000').toISOString(), narrowDateRange: jest.fn(), skip: true, type: NetworkType.details, }; const next: AnomaliesNetworkTableProps = { - startDate: new Date('2000').valueOf(), - endDate: new Date('2000').valueOf(), + startDate: new Date('2000').toISOString(), + endDate: new Date('2000').toISOString(), narrowDateRange: jest.fn(), skip: false, type: NetworkType.details, @@ -126,16 +126,16 @@ describe('network_equality', () => { test('it returns false if flowType is not equal', () => { const prev: AnomaliesNetworkTableProps = { - startDate: new Date('2000').valueOf(), - endDate: new Date('2000').valueOf(), + startDate: new Date('2000').toISOString(), + endDate: new Date('2000').toISOString(), narrowDateRange: jest.fn(), skip: true, type: NetworkType.details, flowTarget: FlowTarget.source, }; const next: AnomaliesNetworkTableProps = { - startDate: new Date('2000').valueOf(), - endDate: new Date('2000').valueOf(), + startDate: new Date('2000').toISOString(), + endDate: new Date('2000').toISOString(), narrowDateRange: jest.fn(), skip: false, type: NetworkType.details, diff --git a/x-pack/plugins/security_solution/public/common/components/ml/types.ts b/x-pack/plugins/security_solution/public/common/components/ml/types.ts index 13bceaa473a84f..a4c4f728b0f8f5 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/types.ts +++ b/x-pack/plugins/security_solution/public/common/components/ml/types.ts @@ -75,8 +75,8 @@ export interface AnomaliesByNetwork { } export interface HostOrNetworkProps { - startDate: number; - endDate: number; + startDate: string; + endDate: string; narrowDateRange: NarrowDateRange; skip: boolean; } diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts index ade76f8e243383..7e508c28c62dfa 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts @@ -80,20 +80,20 @@ const getMockObject = ( global: { linkTo: ['timeline'], timerange: { - from: 1558048243696, + from: '2019-05-16T23:10:43.696Z', fromStr: 'now-24h', kind: 'relative', - to: 1558134643697, + to: '2019-05-17T23:10:43.697Z', toStr: 'now', }, }, timeline: { linkTo: ['global'], timerange: { - from: 1558048243696, + from: '2019-05-16T23:10:43.696Z', fromStr: 'now-24h', kind: 'relative', - to: 1558134643697, + to: '2019-05-17T23:10:43.697Z', toStr: 'now', }, }, @@ -123,7 +123,7 @@ describe('Navigation Breadcrumbs', () => { }, { href: - 'securitySolution:hosts?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))', + "securitySolution:hosts?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", text: 'Hosts', }, { @@ -143,7 +143,7 @@ describe('Navigation Breadcrumbs', () => { { text: 'Network', href: - 'securitySolution:network?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))', + "securitySolution:network?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", }, { text: 'Flows', @@ -162,7 +162,7 @@ describe('Navigation Breadcrumbs', () => { { text: 'Timelines', href: - 'securitySolution:timelines?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))', + "securitySolution:timelines?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", }, ]); }); @@ -177,12 +177,12 @@ describe('Navigation Breadcrumbs', () => { { text: 'Hosts', href: - 'securitySolution:hosts?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))', + "securitySolution:hosts?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", }, { text: 'siem-kibana', href: - 'securitySolution:hosts/siem-kibana?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))', + "securitySolution:hosts/siem-kibana?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", }, { text: 'Authentications', href: '' }, ]); @@ -198,11 +198,11 @@ describe('Navigation Breadcrumbs', () => { { text: 'Network', href: - 'securitySolution:network?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))', + "securitySolution:network?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", }, { text: ipv4, - href: `securitySolution:network/ip/${ipv4}/source?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))`, + href: `securitySolution:network/ip/${ipv4}/source?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`, }, { text: 'Flows', href: '' }, ]); @@ -218,11 +218,11 @@ describe('Navigation Breadcrumbs', () => { { text: 'Network', href: - 'securitySolution:network?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))', + "securitySolution:network?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", }, { text: ipv6, - href: `securitySolution:network/ip/${ipv6Encoded}/source?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))`, + href: `securitySolution:network/ip/${ipv6Encoded}/source?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`, }, { text: 'Flows', href: '' }, ]); @@ -237,12 +237,12 @@ describe('Navigation Breadcrumbs', () => { { text: 'Hosts', href: - 'securitySolution:hosts?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))', + "securitySolution:hosts?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", }, { text: 'siem-kibana', href: - 'securitySolution:hosts/siem-kibana?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))', + "securitySolution:hosts/siem-kibana?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", }, { text: 'Authentications', href: '' }, ]); diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/index.test.tsx index c60feb63241fb9..16cb19f5a0c146 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/index.test.tsx @@ -57,20 +57,20 @@ describe('SIEM Navigation', () => { [CONSTANTS.timerange]: { global: { [CONSTANTS.timerange]: { - from: 1558048243696, + from: '2019-05-16T23:10:43.696Z', fromStr: 'now-24h', kind: 'relative', - to: 1558134643697, + to: '2019-05-17T23:10:43.697Z', toStr: 'now', }, linkTo: ['timeline'], }, timeline: { [CONSTANTS.timerange]: { - from: 1558048243696, + from: '2019-05-16T23:10:43.696Z', fromStr: 'now-24h', kind: 'relative', - to: 1558134643697, + to: '2019-05-17T23:10:43.697Z', toStr: 'now', }, linkTo: ['global'], @@ -160,20 +160,20 @@ describe('SIEM Navigation', () => { global: { linkTo: ['timeline'], timerange: { - from: 1558048243696, + from: '2019-05-16T23:10:43.696Z', fromStr: 'now-24h', kind: 'relative', - to: 1558134643697, + to: '2019-05-17T23:10:43.697Z', toStr: 'now', }, }, timeline: { linkTo: ['global'], timerange: { - from: 1558048243696, + from: '2019-05-16T23:10:43.696Z', fromStr: 'now-24h', kind: 'relative', - to: 1558134643697, + to: '2019-05-17T23:10:43.697Z', toStr: 'now', }, }, @@ -259,20 +259,20 @@ describe('SIEM Navigation', () => { global: { linkTo: ['timeline'], timerange: { - from: 1558048243696, + from: '2019-05-16T23:10:43.696Z', fromStr: 'now-24h', kind: 'relative', - to: 1558134643697, + to: '2019-05-17T23:10:43.697Z', toStr: 'now', }, }, timeline: { linkTo: ['global'], timerange: { - from: 1558048243696, + from: '2019-05-16T23:10:43.696Z', fromStr: 'now-24h', kind: 'relative', - to: 1558134643697, + to: '2019-05-17T23:10:43.697Z', toStr: 'now', }, }, diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/index.test.tsx index f345346d620cb1..b25cf3779801b7 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/index.test.tsx @@ -47,20 +47,20 @@ describe('Tab Navigation', () => { [CONSTANTS.timerange]: { global: { [CONSTANTS.timerange]: { - from: 1558048243696, + from: '2019-05-16T23:10:43.696Z', fromStr: 'now-24h', kind: 'relative', - to: 1558134643697, + to: '2019-05-17T23:10:43.697Z', toStr: 'now', }, linkTo: ['timeline'], }, timeline: { [CONSTANTS.timerange]: { - from: 1558048243696, + from: '2019-05-16T23:10:43.696Z', fromStr: 'now-24h', kind: 'relative', - to: 1558134643697, + to: '2019-05-17T23:10:43.697Z', toStr: 'now', }, linkTo: ['global'], @@ -105,20 +105,20 @@ describe('Tab Navigation', () => { [CONSTANTS.timerange]: { global: { [CONSTANTS.timerange]: { - from: 1558048243696, + from: '2019-05-16T23:10:43.696Z', fromStr: 'now-24h', kind: 'relative', - to: 1558134643697, + to: '2019-05-17T23:10:43.697Z', toStr: 'now', }, linkTo: ['timeline'], }, timeline: { [CONSTANTS.timerange]: { - from: 1558048243696, + from: '2019-05-16T23:10:43.696Z', fromStr: 'now-24h', kind: 'relative', - to: 1558134643697, + to: '2019-05-17T23:10:43.697Z', toStr: 'now', }, linkTo: ['global'], diff --git a/x-pack/plugins/security_solution/public/common/components/stat_items/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/stat_items/index.test.tsx index f548275b36e709..8a78706e17a4cb 100644 --- a/x-pack/plugins/security_solution/public/common/components/stat_items/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/stat_items/index.test.tsx @@ -41,8 +41,8 @@ import { State, createStore } from '../../store'; import { Provider as ReduxStoreProvider } from 'react-redux'; import { KpiNetworkData, KpiHostsData } from '../../../graphql/types'; -const from = new Date('2019-06-15T06:00:00.000Z').valueOf(); -const to = new Date('2019-06-18T06:00:00.000Z').valueOf(); +const from = '2019-06-15T06:00:00.000Z'; +const to = '2019-06-18T06:00:00.000Z'; jest.mock('../charts/areachart', () => { return { AreaChart: () =>
}; @@ -131,18 +131,18 @@ describe('Stat Items Component', () => { { key: 'uniqueSourceIpsHistogram', value: [ - { x: new Date('2019-05-03T13:00:00.000Z').valueOf(), y: 565975 }, - { x: new Date('2019-05-04T01:00:00.000Z').valueOf(), y: 1084366 }, - { x: new Date('2019-05-04T13:00:00.000Z').valueOf(), y: 12280 }, + { x: new Date('2019-05-03T13:00:00.000Z').toISOString(), y: 565975 }, + { x: new Date('2019-05-04T01:00:00.000Z').toISOString(), y: 1084366 }, + { x: new Date('2019-05-04T13:00:00.000Z').toISOString(), y: 12280 }, ], color: '#D36086', }, { key: 'uniqueDestinationIpsHistogram', value: [ - { x: new Date('2019-05-03T13:00:00.000Z').valueOf(), y: 565975 }, - { x: new Date('2019-05-04T01:00:00.000Z').valueOf(), y: 1084366 }, - { x: new Date('2019-05-04T13:00:00.000Z').valueOf(), y: 12280 }, + { x: new Date('2019-05-03T13:00:00.000Z').toISOString(), y: 565975 }, + { x: new Date('2019-05-04T01:00:00.000Z').toISOString(), y: 1084366 }, + { x: new Date('2019-05-04T13:00:00.000Z').toISOString(), y: 12280 }, ], color: '#9170B8', }, diff --git a/x-pack/plugins/security_solution/public/common/components/stat_items/index.tsx b/x-pack/plugins/security_solution/public/common/components/stat_items/index.tsx index dee730059b03a6..183f89d9320f35 100644 --- a/x-pack/plugins/security_solution/public/common/components/stat_items/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/stat_items/index.tsx @@ -66,10 +66,10 @@ export interface StatItems { export interface StatItemsProps extends StatItems { areaChart?: ChartSeriesData[]; barChart?: ChartSeriesData[]; - from: number; + from: string; id: string; narrowDateRange: UpdateDateRange; - to: number; + to: string; } export const numberFormatter = (value: string | number): string => value.toLocaleString(); @@ -160,8 +160,8 @@ export const useKpiMatrixStatus = ( mappings: Readonly, data: KpiHostsData | KpiNetworkData, id: string, - from: number, - to: number, + from: string, + to: string, narrowDateRange: UpdateDateRange ): StatItemsProps[] => { const [statItemsProps, setStatItemsProps] = useState(mappings as StatItemsProps[]); diff --git a/x-pack/plugins/security_solution/public/common/components/super_date_picker/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/super_date_picker/index.test.tsx index 164ca177ee91ad..0795e46c9e45fe 100644 --- a/x-pack/plugins/security_solution/public/common/components/super_date_picker/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/super_date_picker/index.test.tsx @@ -156,8 +156,8 @@ describe('SIEM Super Date Picker', () => { }); test('Make Sure to (end date) is superior than from (start date)', () => { - expect(store.getState().inputs.global.timerange.to).toBeGreaterThan( - store.getState().inputs.global.timerange.from + expect(new Date(store.getState().inputs.global.timerange.to).valueOf()).toBeGreaterThan( + new Date(store.getState().inputs.global.timerange.from).valueOf() ); }); }); @@ -321,7 +321,7 @@ describe('SIEM Super Date Picker', () => { const mapStateToProps = makeMapStateToProps(); const props1 = mapStateToProps(state, { id: 'global' }); const clone = cloneDeep(state); - clone.inputs.global.timerange.from = 999; + clone.inputs.global.timerange.from = '2020-07-07T09:20:18.966Z'; const props2 = mapStateToProps(clone, { id: 'global' }); expect(props1.start).not.toBe(props2.start); }); @@ -330,7 +330,7 @@ describe('SIEM Super Date Picker', () => { const mapStateToProps = makeMapStateToProps(); const props1 = mapStateToProps(state, { id: 'global' }); const clone = cloneDeep(state); - clone.inputs.global.timerange.to = 999; + clone.inputs.global.timerange.to = '2020-07-08T09:20:18.966Z'; const props2 = mapStateToProps(clone, { id: 'global' }); expect(props1.end).not.toBe(props2.end); }); diff --git a/x-pack/plugins/security_solution/public/common/components/super_date_picker/index.tsx b/x-pack/plugins/security_solution/public/common/components/super_date_picker/index.tsx index 84ff1120f6496f..4443d24531b22e 100644 --- a/x-pack/plugins/security_solution/public/common/components/super_date_picker/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/super_date_picker/index.tsx @@ -216,9 +216,9 @@ export const formatDate = ( options?: { roundUp?: boolean; } -) => { +): string => { const momentDate = dateMath.parse(date, options); - return momentDate != null && momentDate.isValid() ? momentDate.valueOf() : 0; + return momentDate != null && momentDate.isValid() ? momentDate.toISOString() : ''; }; export const dispatchUpdateReduxTime = (dispatch: Dispatch) => ({ diff --git a/x-pack/plugins/security_solution/public/common/components/super_date_picker/selectors.test.ts b/x-pack/plugins/security_solution/public/common/components/super_date_picker/selectors.test.ts index 1dafa141542bfd..7cb4ea9ada93fd 100644 --- a/x-pack/plugins/security_solution/public/common/components/super_date_picker/selectors.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/super_date_picker/selectors.test.ts @@ -23,8 +23,8 @@ describe('selectors', () => { kind: 'absolute', fromStr: undefined, toStr: undefined, - from: 0, - to: 0, + from: '2020-07-07T08:20:18.966Z', + to: '2020-07-08T08:20:18.966Z', }; let inputState: InputsRange = { @@ -57,8 +57,8 @@ describe('selectors', () => { kind: 'absolute', fromStr: undefined, toStr: undefined, - from: 0, - to: 0, + from: '2020-07-07T08:20:18.966Z', + to: '2020-07-08T08:20:18.966Z', }; inputState = { @@ -147,8 +147,8 @@ describe('selectors', () => { kind: 'relative', fromStr: '', toStr: '', - from: 1, - to: 0, + from: '2020-07-08T08:20:18.966Z', + to: '2020-07-09T08:20:18.966Z', }; const change: InputsRange = { ...inputState, @@ -179,8 +179,8 @@ describe('selectors', () => { kind: 'relative', fromStr: '', toStr: '', - from: 1, - to: 0, + from: '2020-07-08T08:20:18.966Z', + to: '2020-07-09T08:20:18.966Z', }; const change: InputsRange = { ...inputState, @@ -211,8 +211,8 @@ describe('selectors', () => { kind: 'relative', fromStr: '', toStr: '', - from: 0, - to: 1, + from: '2020-07-08T08:20:18.966Z', + to: '2020-07-09T08:20:18.966Z', }; const change: InputsRange = { ...inputState, @@ -243,8 +243,8 @@ describe('selectors', () => { kind: 'relative', fromStr: '', toStr: '', - from: 0, - to: 0, + from: '2020-07-08T08:20:18.966Z', + to: '2020-07-09T08:20:18.966Z', }; const change: InputsRange = { ...inputState, @@ -275,8 +275,8 @@ describe('selectors', () => { kind: 'relative', fromStr: '', toStr: '', - from: 0, - to: 0, + from: '2020-07-08T08:20:18.966Z', + to: '2020-07-09T08:20:18.966Z', }; const change: InputsRange = { ...inputState, diff --git a/x-pack/plugins/security_solution/public/common/components/top_n/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/top_n/index.test.tsx index c8232b0c3b3cbe..b393e9ae6319b2 100644 --- a/x-pack/plugins/security_solution/public/common/components/top_n/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/top_n/index.test.tsx @@ -88,8 +88,8 @@ const state: State = { kind: 'relative', fromStr: 'now-24h', toStr: 'now', - from: 1586835969047, - to: 1586922369047, + from: '2020-04-14T03:46:09.047Z', + to: '2020-04-15T03:46:09.047Z', }, }, }, @@ -242,7 +242,7 @@ describe('StatefulTopN', () => { test(`provides 'from' via GlobalTime when rendering in a global context`, () => { const props = wrapper.find('[data-test-subj="top-n"]').first().props() as Props; - expect(props.from).toEqual(0); + expect(props.from).toEqual('2020-07-07T08:20:18.966Z'); }); test('provides the global query from Redux state (inputs > global > query) when rendering in a global context', () => { @@ -260,7 +260,7 @@ describe('StatefulTopN', () => { test(`provides 'to' via GlobalTime when rendering in a global context`, () => { const props = wrapper.find('[data-test-subj="top-n"]').first().props() as Props; - expect(props.to).toEqual(1); + expect(props.to).toEqual('2020-07-08T08:20:18.966Z'); }); }); @@ -298,7 +298,7 @@ describe('StatefulTopN', () => { const props = wrapper.find('[data-test-subj="top-n"]').first().props() as Props; expect(props.combinedQueries).toEqual( - '{"bool":{"must":[],"filter":[{"bool":{"filter":[{"bool":{"filter":[{"bool":{"should":[{"match_phrase":{"network.transport":"tcp"}}],"minimum_should_match":1}},{"bool":{"should":[{"exists":{"field":"host.name"}}],"minimum_should_match":1}}]}},{"bool":{"filter":[{"bool":{"should":[{"range":{"@timestamp":{"gte":1586835969047}}}],"minimum_should_match":1}},{"bool":{"should":[{"range":{"@timestamp":{"lte":1586922369047}}}],"minimum_should_match":1}}]}}]}},{"match_phrase":{"source.port":{"query":"30045"}}}],"should":[],"must_not":[]}}' + '{"bool":{"must":[],"filter":[{"bool":{"filter":[{"bool":{"should":[{"match_phrase":{"network.transport":"tcp"}}],"minimum_should_match":1}},{"bool":{"should":[{"exists":{"field":"host.name"}}],"minimum_should_match":1}}]}},{"match_phrase":{"source.port":{"query":"30045"}}}],"should":[],"must_not":[]}}' ); }); @@ -323,7 +323,7 @@ describe('StatefulTopN', () => { test(`provides 'from' via redux state (inputs > timeline > timerange) when rendering in a timeline context`, () => { const props = wrapper.find('[data-test-subj="top-n"]').first().props() as Props; - expect(props.from).toEqual(1586835969047); + expect(props.from).toEqual('2020-04-14T03:46:09.047Z'); }); test('provides an empty query when rendering in a timeline context', () => { @@ -341,7 +341,7 @@ describe('StatefulTopN', () => { test(`provides 'to' via redux state (inputs > timeline > timerange) when rendering in a timeline context`, () => { const props = wrapper.find('[data-test-subj="top-n"]').first().props() as Props; - expect(props.to).toEqual(1586922369047); + expect(props.to).toEqual('2020-04-15T03:46:09.047Z'); }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/top_n/top_n.test.tsx b/x-pack/plugins/security_solution/public/common/components/top_n/top_n.test.tsx index b1979c501c7786..e5a1fb61202850 100644 --- a/x-pack/plugins/security_solution/public/common/components/top_n/top_n.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/top_n/top_n.test.tsx @@ -114,14 +114,14 @@ describe('TopN', () => { defaultView="raw" field={field} filters={[]} - from={1586824307695} + from={'2020-04-14T00:31:47.695Z'} indexPattern={mockIndexPattern} options={defaultOptions} query={query} setAbsoluteRangeDatePicker={setAbsoluteRangeDatePicker} setAbsoluteRangeDatePickerTarget="global" setQuery={jest.fn()} - to={1586910707695} + to={'2020-04-15T00:31:47.695Z'} toggleTopN={toggleTopN} value={value} /> @@ -153,14 +153,14 @@ describe('TopN', () => { defaultView="raw" field={field} filters={[]} - from={1586824307695} + from={'2020-04-14T00:31:47.695Z'} indexPattern={mockIndexPattern} options={defaultOptions} query={query} setAbsoluteRangeDatePicker={setAbsoluteRangeDatePicker} setAbsoluteRangeDatePickerTarget="global" setQuery={jest.fn()} - to={1586910707695} + to={'2020-04-15T00:31:47.695Z'} toggleTopN={toggleTopN} value={value} /> @@ -191,14 +191,14 @@ describe('TopN', () => { defaultView="alert" field={field} filters={[]} - from={1586824307695} + from={'2020-04-14T00:31:47.695Z'} indexPattern={mockIndexPattern} options={defaultOptions} query={query} setAbsoluteRangeDatePicker={setAbsoluteRangeDatePicker} setAbsoluteRangeDatePickerTarget="global" setQuery={jest.fn()} - to={1586910707695} + to={'2020-04-15T00:31:47.695Z'} toggleTopN={toggleTopN} value={value} /> @@ -228,14 +228,14 @@ describe('TopN', () => { defaultView="all" field={field} filters={[]} - from={1586824307695} + from={'2020-04-14T00:31:47.695Z'} indexPattern={mockIndexPattern} options={allEvents} query={query} setAbsoluteRangeDatePicker={setAbsoluteRangeDatePicker} setAbsoluteRangeDatePickerTarget="global" setQuery={jest.fn()} - to={1586910707695} + to={'2020-04-15T00:31:47.695Z'} toggleTopN={jest.fn()} value={value} /> diff --git a/x-pack/plugins/security_solution/public/common/components/top_n/top_n.tsx b/x-pack/plugins/security_solution/public/common/components/top_n/top_n.tsx index 5e2fd998224c63..064241a7216f46 100644 --- a/x-pack/plugins/security_solution/public/common/components/top_n/top_n.tsx +++ b/x-pack/plugins/security_solution/public/common/components/top_n/top_n.tsx @@ -54,8 +54,8 @@ export interface Props extends Pick; setAbsoluteRangeDatePickerTarget: InputsModelId; timelineId?: string; diff --git a/x-pack/plugins/security_solution/public/common/components/url_state/__mocks__/normalize_time_range.ts b/x-pack/plugins/security_solution/public/common/components/url_state/__mocks__/normalize_time_range.ts new file mode 100644 index 00000000000000..37c839c2969d43 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/url_state/__mocks__/normalize_time_range.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export const normalizeTimeRange = () => ({ + from: '2020-07-07T08:20:18.966Z', + to: '2020-07-08T08:20:18.966Z', +}); diff --git a/x-pack/plugins/security_solution/public/common/components/url_state/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/url_state/index.test.tsx index eeeaacc25a15ec..9d0d9e7b250a05 100644 --- a/x-pack/plugins/security_solution/public/common/components/url_state/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/url_state/index.test.tsx @@ -38,7 +38,7 @@ jest.mock('../../utils/route/use_route_spy', () => ({ jest.mock('../super_date_picker', () => ({ formatDate: (date: string) => { - return 11223344556677; + return '2020-01-01T00:00:00.000Z'; }, })); @@ -53,11 +53,14 @@ jest.mock('../../lib/kibana', () => ({ }, }, }), + KibanaServices: { + get: jest.fn(() => ({ uiSettings: { get: () => ({ from: 'now-24h', to: 'now' }) } })), + }, })); describe('UrlStateContainer', () => { afterEach(() => { - jest.resetAllMocks(); + jest.clearAllMocks(); }); describe('handleInitialize', () => { describe('URL state updates redux', () => { @@ -75,19 +78,19 @@ describe('UrlStateContainer', () => { mount( useUrlStateHooks(args)} />); expect(mockSetRelativeRangeDatePicker.mock.calls[1][0]).toEqual({ - from: 11223344556677, + from: '2020-01-01T00:00:00.000Z', fromStr: 'now-1d/d', kind: 'relative', - to: 11223344556677, + to: '2020-01-01T00:00:00.000Z', toStr: 'now-1d/d', id: 'global', }); expect(mockSetRelativeRangeDatePicker.mock.calls[0][0]).toEqual({ - from: 11223344556677, + from: '2020-01-01T00:00:00.000Z', fromStr: 'now-15m', kind: 'relative', - to: 11223344556677, + to: '2020-01-01T00:00:00.000Z', toStr: 'now', id: 'timeline', }); @@ -104,16 +107,16 @@ describe('UrlStateContainer', () => { mount( useUrlStateHooks(args)} />); expect(mockSetAbsoluteRangeDatePicker.mock.calls[1][0]).toEqual({ - from: 1556736012685, + from: '2019-05-01T18:40:12.685Z', kind: 'absolute', - to: 1556822416082, + to: '2019-05-02T18:40:16.082Z', id: 'global', }); expect(mockSetAbsoluteRangeDatePicker.mock.calls[0][0]).toEqual({ - from: 1556736012685, + from: '2019-05-01T18:40:12.685Z', kind: 'absolute', - to: 1556822416082, + to: '2019-05-02T18:40:16.082Z', id: 'timeline', }); } @@ -157,7 +160,7 @@ describe('UrlStateContainer', () => { ).toEqual({ hash: '', pathname: examplePath, - search: `?query=(language:kuery,query:'host.name:%22siem-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))`, + search: `?query=(language:kuery,query:'host.name:%22siem-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`, state: '', }); } @@ -195,10 +198,10 @@ describe('UrlStateContainer', () => { if (CONSTANTS.detectionsPage === page) { expect(mockSetRelativeRangeDatePicker.mock.calls[3][0]).toEqual({ - from: 11223344556677, + from: '2020-01-01T00:00:00.000Z', fromStr: 'now-1d/d', kind: 'relative', - to: 11223344556677, + to: '2020-01-01T00:00:00.000Z', toStr: 'now-1d/d', id: 'global', }); diff --git a/x-pack/plugins/security_solution/public/common/components/url_state/index_mocked.test.tsx b/x-pack/plugins/security_solution/public/common/components/url_state/index_mocked.test.tsx index f7502661da308b..723f2d235864fe 100644 --- a/x-pack/plugins/security_solution/public/common/components/url_state/index_mocked.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/url_state/index_mocked.test.tsx @@ -54,20 +54,20 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => [CONSTANTS.timerange]: { global: { [CONSTANTS.timerange]: { - from: 0, + from: '2020-07-07T08:20:18.966Z', fromStr: 'now-24h', kind: 'relative', - to: 1, + to: '2020-07-08T08:20:18.966Z', toStr: 'now', }, linkTo: ['timeline'], }, timeline: { [CONSTANTS.timerange]: { - from: 0, + from: '2020-07-07T08:20:18.966Z', fromStr: 'now-24h', kind: 'relative', - to: 1, + to: '2020-07-08T08:20:18.966Z', toStr: 'now', }, linkTo: ['global'], @@ -83,7 +83,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => hash: '', pathname: '/network', search: - "?query=(language:kuery,query:'host.name:%22siem-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:0,fromStr:now-24h,kind:relative,to:1,toStr:now)),timeline:(linkTo:!(global),timerange:(from:0,fromStr:now-24h,kind:relative,to:1,toStr:now)))", + "?query=(language:kuery,query:'host.name:%22siem-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", state: '', }); }); @@ -114,7 +114,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => hash: '', pathname: '/network', search: - "?query=(language:kuery,query:'host.name:%22siem-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))", + "?query=(language:kuery,query:'host.name:%22siem-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", state: '', }); }); @@ -147,7 +147,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => hash: '', pathname: '/network', search: - '?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))&timeline=(id:hello_timeline_id,isOpen:!t)', + "?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))&timeline=(id:hello_timeline_id,isOpen:!t)", state: '', }); }); @@ -176,7 +176,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => hash: '', pathname: examplePath, search: - '?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))', + "?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", state: '', }); } @@ -204,7 +204,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => expect( mockHistory.replace.mock.calls[mockHistory.replace.mock.calls.length - 1][0].search ).toEqual( - '?timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))' + "?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))" ); wrapper.setProps({ hookProps: updatedProps }); @@ -213,7 +213,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => expect( mockHistory.replace.mock.calls[mockHistory.replace.mock.calls.length - 1][0].search ).toEqual( - "?query=(language:kuery,query:'host.name:%22siem-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)),timeline:(linkTo:!(global),timerange:(from:1558048243696,fromStr:now-24h,kind:relative,to:1558134643697,toStr:now)))" + "?query=(language:kuery,query:'host.name:%22siem-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))" ); }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/url_state/initialize_redux_by_url.tsx b/x-pack/plugins/security_solution/public/common/components/url_state/initialize_redux_by_url.tsx index ab03e2199474c6..6eccf52ec72da2 100644 --- a/x-pack/plugins/security_solution/public/common/components/url_state/initialize_redux_by_url.tsx +++ b/x-pack/plugins/security_solution/public/common/components/url_state/initialize_redux_by_url.tsx @@ -120,6 +120,7 @@ const updateTimerange = (newUrlStateString: string, dispatch: Dispatch) => { const absoluteRange = normalizeTimeRange( get('timeline.timerange', timerangeStateData) ); + dispatch( inputsActions.setAbsoluteRangeDatePicker({ ...absoluteRange, @@ -127,10 +128,12 @@ const updateTimerange = (newUrlStateString: string, dispatch: Dispatch) => { }) ); } + if (timelineType === 'relative') { const relativeRange = normalizeTimeRange( get('timeline.timerange', timerangeStateData) ); + dispatch( inputsActions.setRelativeRangeDatePicker({ ...relativeRange, @@ -145,6 +148,7 @@ const updateTimerange = (newUrlStateString: string, dispatch: Dispatch) => { const absoluteRange = normalizeTimeRange( get('global.timerange', timerangeStateData) ); + dispatch( inputsActions.setAbsoluteRangeDatePicker({ ...absoluteRange, @@ -156,6 +160,7 @@ const updateTimerange = (newUrlStateString: string, dispatch: Dispatch) => { const relativeRange = normalizeTimeRange( get('global.timerange', timerangeStateData) ); + dispatch( inputsActions.setRelativeRangeDatePicker({ ...relativeRange, diff --git a/x-pack/plugins/security_solution/public/common/components/url_state/normalize_time_range.test.ts b/x-pack/plugins/security_solution/public/common/components/url_state/normalize_time_range.test.ts index dcdadf0f340727..d0cd9a26850777 100644 --- a/x-pack/plugins/security_solution/public/common/components/url_state/normalize_time_range.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/url_state/normalize_time_range.test.ts @@ -13,8 +13,32 @@ import { isRelativeTimeRange, } from '../../store/inputs/model'; +import { getTimeRangeSettings } from '../../utils/default_date_settings'; + +const getTimeRangeSettingsMock = getTimeRangeSettings as jest.Mock; + +jest.mock('../../utils/default_date_settings'); +jest.mock('@elastic/datemath', () => ({ + parse: (date: string) => { + if (date === 'now') { + return { toISOString: () => '2020-07-08T08:20:18.966Z' }; + } + + if (date === 'now-24h') { + return { toISOString: () => '2020-07-07T08:20:18.966Z' }; + } + }, +})); + +getTimeRangeSettingsMock.mockImplementation(() => ({ + from: '2020-07-04T08:20:18.966Z', + to: '2020-07-05T08:20:18.966Z', + fromStr: 'now-24h', + toStr: 'now', +})); + describe('#normalizeTimeRange', () => { - test('Absolute time range returns empty strings as 0', () => { + test('Absolute time range returns defaults for empty strings', () => { const dateTimeRange: URLTimeRange = { kind: 'absolute', fromStr: undefined, @@ -25,30 +49,8 @@ describe('#normalizeTimeRange', () => { if (isAbsoluteTimeRange(dateTimeRange)) { const expected: AbsoluteTimeRange = { kind: 'absolute', - from: 0, - to: 0, - fromStr: undefined, - toStr: undefined, - }; - expect(normalizeTimeRange(dateTimeRange)).toEqual(expected); - } else { - throw new Error('Was expecting date time range to be a AbsoluteTimeRange'); - } - }); - - test('Absolute time range returns string with empty spaces as 0', () => { - const dateTimeRange: URLTimeRange = { - kind: 'absolute', - fromStr: undefined, - toStr: undefined, - from: ' ', - to: ' ', - }; - if (isAbsoluteTimeRange(dateTimeRange)) { - const expected: AbsoluteTimeRange = { - kind: 'absolute', - from: 0, - to: 0, + from: '2020-07-04T08:20:18.966Z', + to: '2020-07-05T08:20:18.966Z', fromStr: undefined, toStr: undefined, }; @@ -71,8 +73,8 @@ describe('#normalizeTimeRange', () => { if (isAbsoluteTimeRange(dateTimeRange)) { const expected: AbsoluteTimeRange = { kind: 'absolute', - from: from.valueOf(), - to: to.valueOf(), + from: from.toISOString(), + to: to.toISOString(), fromStr: undefined, toStr: undefined, }; @@ -89,14 +91,14 @@ describe('#normalizeTimeRange', () => { kind: 'absolute', fromStr: undefined, toStr: undefined, - from: from.valueOf(), - to: to.valueOf(), + from: from.toISOString(), + to: to.toISOString(), }; if (isAbsoluteTimeRange(dateTimeRange)) { const expected: AbsoluteTimeRange = { kind: 'absolute', - from: from.valueOf(), - to: to.valueOf(), + from: from.toISOString(), + to: to.toISOString(), fromStr: undefined, toStr: undefined, }; @@ -113,14 +115,14 @@ describe('#normalizeTimeRange', () => { kind: 'absolute', fromStr: undefined, toStr: undefined, - from: `${from.valueOf()}`, - to: `${to.valueOf()}`, + from: `${from.toISOString()}`, + to: `${to.toISOString()}`, }; if (isAbsoluteTimeRange(dateTimeRange)) { const expected: AbsoluteTimeRange = { kind: 'absolute', - from: from.valueOf(), - to: to.valueOf(), + from: from.toISOString(), + to: to.toISOString(), fromStr: undefined, toStr: undefined, }; @@ -130,7 +132,7 @@ describe('#normalizeTimeRange', () => { } }); - test('Absolute time range returns NaN with from and to when garbage is sent in', () => { + test('Absolute time range returns defaults when garbage is sent in', () => { const to = 'garbage'; const from = 'garbage'; const dateTimeRange: URLTimeRange = { @@ -143,8 +145,8 @@ describe('#normalizeTimeRange', () => { if (isAbsoluteTimeRange(dateTimeRange)) { const expected: AbsoluteTimeRange = { kind: 'absolute', - from: NaN, - to: NaN, + from: '2020-07-04T08:20:18.966Z', + to: '2020-07-05T08:20:18.966Z', fromStr: undefined, toStr: undefined, }; @@ -154,7 +156,7 @@ describe('#normalizeTimeRange', () => { } }); - test('Relative time range returns empty strings as 0', () => { + test('Relative time range returns defaults fro empty strings', () => { const dateTimeRange: URLTimeRange = { kind: 'relative', fromStr: '', @@ -165,30 +167,8 @@ describe('#normalizeTimeRange', () => { if (isRelativeTimeRange(dateTimeRange)) { const expected: RelativeTimeRange = { kind: 'relative', - from: 0, - to: 0, - fromStr: '', - toStr: '', - }; - expect(normalizeTimeRange(dateTimeRange)).toEqual(expected); - } else { - throw new Error('Was expecting date time range to be a RelativeTimeRange'); - } - }); - - test('Relative time range returns string with empty spaces as 0', () => { - const dateTimeRange: URLTimeRange = { - kind: 'relative', - fromStr: '', - toStr: '', - from: ' ', - to: ' ', - }; - if (isRelativeTimeRange(dateTimeRange)) { - const expected: RelativeTimeRange = { - kind: 'relative', - from: 0, - to: 0, + from: '2020-07-04T08:20:18.966Z', + to: '2020-07-05T08:20:18.966Z', fromStr: '', toStr: '', }; @@ -211,8 +191,8 @@ describe('#normalizeTimeRange', () => { if (isRelativeTimeRange(dateTimeRange)) { const expected: RelativeTimeRange = { kind: 'relative', - from: from.valueOf(), - to: to.valueOf(), + from: from.toISOString(), + to: to.toISOString(), fromStr: '', toStr: '', }; @@ -229,14 +209,14 @@ describe('#normalizeTimeRange', () => { kind: 'relative', fromStr: '', toStr: '', - from: from.valueOf(), - to: to.valueOf(), + from: from.toISOString(), + to: to.toISOString(), }; if (isRelativeTimeRange(dateTimeRange)) { const expected: RelativeTimeRange = { kind: 'relative', - from: from.valueOf(), - to: to.valueOf(), + from: from.toISOString(), + to: to.toISOString(), fromStr: '', toStr: '', }; @@ -253,14 +233,14 @@ describe('#normalizeTimeRange', () => { kind: 'relative', fromStr: '', toStr: '', - from: `${from.valueOf()}`, - to: `${to.valueOf()}`, + from: `${from.toISOString()}`, + to: `${to.toISOString()}`, }; if (isRelativeTimeRange(dateTimeRange)) { const expected: RelativeTimeRange = { kind: 'relative', - from: from.valueOf(), - to: to.valueOf(), + from: from.toISOString(), + to: to.toISOString(), fromStr: '', toStr: '', }; @@ -270,7 +250,7 @@ describe('#normalizeTimeRange', () => { } }); - test('Relative time range returns NaN with from and to when garbage is sent in', () => { + test('Relative time range returns defaults when garbage is sent in', () => { const to = 'garbage'; const from = 'garbage'; const dateTimeRange: URLTimeRange = { @@ -283,8 +263,8 @@ describe('#normalizeTimeRange', () => { if (isRelativeTimeRange(dateTimeRange)) { const expected: RelativeTimeRange = { kind: 'relative', - from: NaN, - to: NaN, + from: '2020-07-04T08:20:18.966Z', + to: '2020-07-05T08:20:18.966Z', fromStr: '', toStr: '', }; diff --git a/x-pack/plugins/security_solution/public/common/components/url_state/normalize_time_range.ts b/x-pack/plugins/security_solution/public/common/components/url_state/normalize_time_range.ts index 851f89dcd2a5a6..6dc0949665530c 100644 --- a/x-pack/plugins/security_solution/public/common/components/url_state/normalize_time_range.ts +++ b/x-pack/plugins/security_solution/public/common/components/url_state/normalize_time_range.ts @@ -5,13 +5,20 @@ */ import { URLTimeRange } from '../../store/inputs/model'; +import { getTimeRangeSettings } from '../../utils/default_date_settings'; import { getMaybeDate } from '../formatted_date/maybe_date'; -export const normalizeTimeRange = (dateRange: T): T => { +export const normalizeTimeRange = < + T extends URLTimeRange | { to: string | number; from: string | number } +>( + dateRange: T, + uiSettings = true +): T => { const maybeTo = getMaybeDate(dateRange.to); const maybeFrom = getMaybeDate(dateRange.from); - const to: number = maybeTo.isValid() ? maybeTo.valueOf() : Number(dateRange.to); - const from: number = maybeFrom.isValid() ? maybeFrom.valueOf() : Number(dateRange.from); + const { to: benchTo, from: benchFrom } = getTimeRangeSettings(uiSettings); + const to: string = maybeTo.isValid() ? maybeTo.toISOString() : benchTo; + const from: string = maybeFrom.isValid() ? maybeFrom.toISOString() : benchFrom; return { ...dateRange, to, diff --git a/x-pack/plugins/security_solution/public/common/components/url_state/test_dependencies.ts b/x-pack/plugins/security_solution/public/common/components/url_state/test_dependencies.ts index dec1672b076eb5..8d471e843320c2 100644 --- a/x-pack/plugins/security_solution/public/common/components/url_state/test_dependencies.ts +++ b/x-pack/plugins/security_solution/public/common/components/url_state/test_dependencies.ts @@ -92,20 +92,20 @@ export const defaultProps: UrlStateContainerPropTypes = { [CONSTANTS.timerange]: { global: { [CONSTANTS.timerange]: { - from: 1558048243696, + from: '2019-05-16T23:10:43.696Z', fromStr: 'now-24h', kind: 'relative', - to: 1558134643697, + to: '2019-05-17T23:10:43.697Z', toStr: 'now', }, linkTo: ['timeline'], }, timeline: { [CONSTANTS.timerange]: { - from: 1558048243696, + from: '2019-05-16T23:10:43.696Z', fromStr: 'now-24h', kind: 'relative', - to: 1558134643697, + to: '2019-05-17T23:10:43.697Z', toStr: 'now', }, linkTo: ['global'], diff --git a/x-pack/plugins/security_solution/public/common/components/utils.ts b/x-pack/plugins/security_solution/public/common/components/utils.ts index ff022fd7d763d7..3620b09495eb6d 100644 --- a/x-pack/plugins/security_solution/public/common/components/utils.ts +++ b/x-pack/plugins/security_solution/public/common/components/utils.ts @@ -20,7 +20,7 @@ export const getDaysDiff = (minDate: moment.Moment, maxDate: moment.Moment) => { return diff; }; -export const histogramDateTimeFormatter = (domain: [number, number] | null, fixedDiff?: number) => { +export const histogramDateTimeFormatter = (domain: [string, string] | null, fixedDiff?: number) => { const diff = fixedDiff ?? getDaysDiff(moment(domain![0]), moment(domain![1])); const format = niceTimeFormatByDay(diff); return timeFormatter(format); diff --git a/x-pack/plugins/security_solution/public/common/containers/events/last_event_time/index.ts b/x-pack/plugins/security_solution/public/common/containers/events/last_event_time/index.ts index 6050dafc0b1910..00b78c3a965504 100644 --- a/x-pack/plugins/security_solution/public/common/containers/events/last_event_time/index.ts +++ b/x-pack/plugins/security_solution/public/common/containers/events/last_event_time/index.ts @@ -19,6 +19,7 @@ import { useUiSetting$ } from '../../../lib/kibana'; import { LastEventTimeGqlQuery } from './last_event_time.gql_query'; import { useApolloClient } from '../../../utils/apollo_context'; +import { useWithSource } from '../../source'; export interface LastEventTimeArgs { id: string; @@ -44,6 +45,8 @@ export function useLastEventTimeQuery( const [currentIndexKey, updateCurrentIndexKey] = useState(null); const [defaultIndex] = useUiSetting$(DEFAULT_INDEX_KEY); const apolloClient = useApolloClient(); + const { docValueFields } = useWithSource(sourceId); + async function fetchLastEventTime(signal: AbortSignal) { updateLoading(true); if (apolloClient) { @@ -52,6 +55,7 @@ export function useLastEventTimeQuery( query: LastEventTimeGqlQuery, fetchPolicy: 'cache-first', variables: { + docValueFields, sourceId, indexKey, details, diff --git a/x-pack/plugins/security_solution/public/common/containers/events/last_event_time/last_event_time.gql_query.ts b/x-pack/plugins/security_solution/public/common/containers/events/last_event_time/last_event_time.gql_query.ts index 049c73b607b7e5..36305ef0dc8820 100644 --- a/x-pack/plugins/security_solution/public/common/containers/events/last_event_time/last_event_time.gql_query.ts +++ b/x-pack/plugins/security_solution/public/common/containers/events/last_event_time/last_event_time.gql_query.ts @@ -12,10 +12,16 @@ export const LastEventTimeGqlQuery = gql` $indexKey: LastEventIndexKey! $details: LastTimeDetails! $defaultIndex: [String!]! + $docValueFields: [docValueFieldsInput!]! ) { source(id: $sourceId) { id - LastEventTime(indexKey: $indexKey, details: $details, defaultIndex: $defaultIndex) { + LastEventTime( + indexKey: $indexKey + details: $details + defaultIndex: $defaultIndex + docValueFields: $docValueFields + ) { lastSeen } } diff --git a/x-pack/plugins/security_solution/public/common/containers/events/last_event_time/mock.ts b/x-pack/plugins/security_solution/public/common/containers/events/last_event_time/mock.ts index 938473f92782a7..bdeb1db4e1b284 100644 --- a/x-pack/plugins/security_solution/public/common/containers/events/last_event_time/mock.ts +++ b/x-pack/plugins/security_solution/public/common/containers/events/last_event_time/mock.ts @@ -44,6 +44,7 @@ export const mockLastEventTimeQuery: MockLastEventTimeQuery[] = [ indexKey: LastEventIndexKey.hosts, details: {}, defaultIndex: DEFAULT_INDEX_PATTERN, + docValueFields: [], }, }, result: { diff --git a/x-pack/plugins/security_solution/public/common/containers/global_time/index.tsx b/x-pack/plugins/security_solution/public/common/containers/global_time/index.tsx new file mode 100644 index 00000000000000..f2545c1642d493 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/containers/global_time/index.tsx @@ -0,0 +1,98 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useCallback, useState, useEffect } from 'react'; +import { connect, ConnectedProps } from 'react-redux'; + +import { inputsModel, inputsSelectors, State } from '../../store'; +import { inputsActions } from '../../store/actions'; + +interface SetQuery { + id: string; + inspect: inputsModel.InspectQuery | null; + loading: boolean; + refetch: inputsModel.Refetch | inputsModel.RefetchKql; +} + +export interface GlobalTimeArgs { + from: string; + to: string; + setQuery: ({ id, inspect, loading, refetch }: SetQuery) => void; + deleteQuery?: ({ id }: { id: string }) => void; + isInitializing: boolean; +} + +interface OwnProps { + children: (args: GlobalTimeArgs) => React.ReactNode; +} + +type GlobalTimeProps = OwnProps & PropsFromRedux; + +export const GlobalTimeComponent: React.FC = ({ + children, + deleteAllQuery, + deleteOneQuery, + from, + to, + setGlobalQuery, +}) => { + const [isInitializing, setIsInitializing] = useState(true); + + const setQuery = useCallback( + ({ id, inspect, loading, refetch }: SetQuery) => + setGlobalQuery({ inputId: 'global', id, inspect, loading, refetch }), + [setGlobalQuery] + ); + + const deleteQuery = useCallback( + ({ id }: { id: string }) => deleteOneQuery({ inputId: 'global', id }), + [deleteOneQuery] + ); + + useEffect(() => { + if (isInitializing) { + setIsInitializing(false); + } + return () => { + deleteAllQuery({ id: 'global' }); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return ( + <> + {children({ + isInitializing, + from, + to, + setQuery, + deleteQuery, + })} + + ); +}; + +const mapStateToProps = (state: State) => { + const timerange: inputsModel.TimeRange = inputsSelectors.globalTimeRangeSelector(state); + return { + from: timerange.from, + to: timerange.to, + }; +}; + +const mapDispatchToProps = { + deleteAllQuery: inputsActions.deleteAllQuery, + deleteOneQuery: inputsActions.deleteOneQuery, + setGlobalQuery: inputsActions.setQuery, +}; + +export const connector = connect(mapStateToProps, mapDispatchToProps); + +type PropsFromRedux = ConnectedProps; + +export const GlobalTime = connector(React.memo(GlobalTimeComponent)); + +GlobalTime.displayName = 'GlobalTime'; diff --git a/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.test.tsx b/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.test.tsx index cb988d7ebf1901..6e780e6b06b521 100644 --- a/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/matrix_histogram/index.test.tsx @@ -61,13 +61,13 @@ describe('useQuery', () => { }); const TestComponent = () => { result = useQuery({ - endDate: 100, + endDate: '2020-07-07T08:20:00.000Z', errorMessage: 'fakeErrorMsg', filterQuery: '', histogramType: HistogramType.alerts, isInspected: false, stackByField: 'fakeField', - startDate: 0, + startDate: '2020-07-07T08:08:00.000Z', }); return
; @@ -85,8 +85,8 @@ describe('useQuery', () => { sourceId: 'default', timerange: { interval: '12h', - from: 0, - to: 100, + from: '2020-07-07T08:08:00.000Z', + to: '2020-07-07T08:20:00.000Z', }, defaultIndex: 'mockDefaultIndex', inspect: false, @@ -123,13 +123,13 @@ describe('useQuery', () => { }); const TestComponent = () => { result = useQuery({ - endDate: 100, + endDate: '2020-07-07T08:20:18.966Z', errorMessage: 'fakeErrorMsg', filterQuery: '', histogramType: HistogramType.alerts, isInspected: false, stackByField: 'fakeField', - startDate: 0, + startDate: '2020-07-08T08:20:18.966Z', }); return
; diff --git a/x-pack/plugins/security_solution/public/common/containers/query_template.tsx b/x-pack/plugins/security_solution/public/common/containers/query_template.tsx index fdc95c1dadfe16..eaa43c255a944a 100644 --- a/x-pack/plugins/security_solution/public/common/containers/query_template.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/query_template.tsx @@ -9,14 +9,18 @@ import React from 'react'; import { FetchMoreOptions, FetchMoreQueryOptions, OperationVariables } from 'react-apollo'; import { ESQuery } from '../../../common/typed_json'; +import { DocValueFields } from './source'; + +export { DocValueFields }; export interface QueryTemplateProps { + docValueFields?: DocValueFields[]; id?: string; - endDate?: number; + endDate?: string; filterQuery?: ESQuery | string; skip?: boolean; sourceId: string; - startDate?: number; + startDate?: string; } // eslint-disable-next-line @typescript-eslint/no-explicit-any export type FetchMoreOptionsArgs = FetchMoreQueryOptions & diff --git a/x-pack/plugins/security_solution/public/common/containers/query_template_paginated.tsx b/x-pack/plugins/security_solution/public/common/containers/query_template_paginated.tsx index 446e1125b2807e..f40ae4d31c586e 100644 --- a/x-pack/plugins/security_solution/public/common/containers/query_template_paginated.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/query_template_paginated.tsx @@ -13,14 +13,18 @@ import deepEqual from 'fast-deep-equal'; import { ESQuery } from '../../../common/typed_json'; import { inputsModel } from '../store/model'; import { generateTablePaginationOptions } from '../components/paginated_table/helpers'; +import { DocValueFields } from './source'; + +export { DocValueFields }; export interface QueryTemplatePaginatedProps { + docValueFields?: DocValueFields[]; id?: string; - endDate?: number; + endDate?: string; filterQuery?: ESQuery | string; skip?: boolean; sourceId: string; - startDate?: number; + startDate?: string; } // eslint-disable-next-line @typescript-eslint/no-explicit-any type FetchMoreOptionsArgs = FetchMoreQueryOptions & diff --git a/x-pack/plugins/security_solution/public/common/containers/source/index.test.tsx b/x-pack/plugins/security_solution/public/common/containers/source/index.test.tsx index bfde17723aef48..03ad6ad3396f89 100644 --- a/x-pack/plugins/security_solution/public/common/containers/source/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/source/index.test.tsx @@ -25,6 +25,7 @@ describe('Index Fields & Browser Fields', () => { return expect(initialResult).toEqual({ browserFields: {}, + docValueFields: [], errorMessage: null, indexPattern: { fields: [], @@ -56,6 +57,16 @@ describe('Index Fields & Browser Fields', () => { current: { indicesExist: true, browserFields: mockBrowserFields, + docValueFields: [ + { + field: '@timestamp', + format: 'date_time', + }, + { + field: 'event.end', + format: 'date_time', + }, + ], indexPattern: { fields: mockIndexFields, title: diff --git a/x-pack/plugins/security_solution/public/common/containers/source/index.tsx b/x-pack/plugins/security_solution/public/common/containers/source/index.tsx index 4f42f20c45ae16..9b7dfe84277c6e 100644 --- a/x-pack/plugins/security_solution/public/common/containers/source/index.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/source/index.tsx @@ -33,6 +33,11 @@ export interface BrowserField { type: string; } +export interface DocValueFields { + field: string; + format: string; +} + export type BrowserFields = Readonly>>; export const getAllBrowserFields = (browserFields: BrowserFields): Array> => @@ -75,14 +80,38 @@ export const getBrowserFields = memoizeOne( (newArgs, lastArgs) => newArgs[0] === lastArgs[0] ); +export const getdocValueFields = memoizeOne( + (_title: string, fields: IndexField[]): DocValueFields[] => + fields && fields.length > 0 + ? fields.reduce((accumulator: DocValueFields[], field: IndexField) => { + if (field.type === 'date' && accumulator.length < 100) { + const format: string = + field.format != null && !isEmpty(field.format) ? field.format : 'date_time'; + return [ + ...accumulator, + { + field: field.name, + format, + }, + ]; + } + return accumulator; + }, []) + : [], + // Update the value only if _title has changed + (newArgs, lastArgs) => newArgs[0] === lastArgs[0] +); + export const indicesExistOrDataTemporarilyUnavailable = ( indicesExist: boolean | null | undefined ) => indicesExist || isUndefined(indicesExist); const EMPTY_BROWSER_FIELDS = {}; +const EMPTY_DOCVALUE_FIELD: DocValueFields[] = []; interface UseWithSourceState { browserFields: BrowserFields; + docValueFields: DocValueFields[]; errorMessage: string | null; indexPattern: IIndexPattern; indicesExist: boolean | undefined | null; @@ -104,6 +133,7 @@ export const useWithSource = ( const [state, setState] = useState({ browserFields: EMPTY_BROWSER_FIELDS, + docValueFields: EMPTY_DOCVALUE_FIELD, errorMessage: null, indexPattern: getIndexFields(defaultIndex.join(), []), indicesExist: indicesExistOrDataTemporarilyUnavailable(undefined), @@ -146,6 +176,10 @@ export const useWithSource = ( defaultIndex.join(), get('data.source.status.indexFields', result) ), + docValueFields: getdocValueFields( + defaultIndex.join(), + get('data.source.status.indexFields', result) + ), indexPattern: getIndexFields( defaultIndex.join(), get('data.source.status.indexFields', result) diff --git a/x-pack/plugins/security_solution/public/common/containers/source/mock.ts b/x-pack/plugins/security_solution/public/common/containers/source/mock.ts index 55e8b6ac02b128..bba6a15d739709 100644 --- a/x-pack/plugins/security_solution/public/common/containers/source/mock.ts +++ b/x-pack/plugins/security_solution/public/common/containers/source/mock.ts @@ -6,7 +6,7 @@ import { DEFAULT_INDEX_PATTERN } from '../../../../common/constants'; -import { BrowserFields } from '.'; +import { BrowserFields, DocValueFields } from '.'; import { sourceQuery } from './index.gql_query'; export const mocksSource = [ @@ -697,3 +697,14 @@ export const mockBrowserFields: BrowserFields = { }, }, }; + +export const mockDocValueFields: DocValueFields[] = [ + { + field: '@timestamp', + format: 'date_time', + }, + { + field: 'event.end', + format: 'date_time', + }, +]; diff --git a/x-pack/plugins/security_solution/public/common/mock/global_state.ts b/x-pack/plugins/security_solution/public/common/mock/global_state.ts index 89f100992e1b9f..2849e8ffabd36e 100644 --- a/x-pack/plugins/security_solution/public/common/mock/global_state.ts +++ b/x-pack/plugins/security_solution/public/common/mock/global_state.ts @@ -156,7 +156,13 @@ export const mockGlobalState: State = { }, inputs: { global: { - timerange: { kind: 'relative', fromStr: DEFAULT_FROM, toStr: DEFAULT_TO, from: 0, to: 1 }, + timerange: { + kind: 'relative', + fromStr: DEFAULT_FROM, + toStr: DEFAULT_TO, + from: '2020-07-07T08:20:18.966Z', + to: '2020-07-08T08:20:18.966Z', + }, linkTo: ['timeline'], queries: [], policy: { kind: DEFAULT_INTERVAL_TYPE, duration: DEFAULT_INTERVAL_VALUE }, @@ -167,7 +173,13 @@ export const mockGlobalState: State = { filters: [], }, timeline: { - timerange: { kind: 'relative', fromStr: DEFAULT_FROM, toStr: DEFAULT_TO, from: 0, to: 1 }, + timerange: { + kind: 'relative', + fromStr: DEFAULT_FROM, + toStr: DEFAULT_TO, + from: '2020-07-07T08:20:18.966Z', + to: '2020-07-08T08:20:18.966Z', + }, linkTo: ['global'], queries: [], policy: { kind: DEFAULT_INTERVAL_TYPE, duration: DEFAULT_INTERVAL_VALUE }, @@ -211,8 +223,8 @@ export const mockGlobalState: State = { templateTimelineVersion: null, noteIds: [], dateRange: { - start: 0, - end: 0, + start: '2020-07-07T08:20:18.966Z', + end: '2020-07-08T08:20:18.966Z', }, selectedEventIds: {}, show: false, diff --git a/x-pack/plugins/security_solution/public/common/mock/timeline_results.ts b/x-pack/plugins/security_solution/public/common/mock/timeline_results.ts index b1df41a19aebe4..a415ab75f13ea5 100644 --- a/x-pack/plugins/security_solution/public/common/mock/timeline_results.ts +++ b/x-pack/plugins/security_solution/public/common/mock/timeline_results.ts @@ -2091,8 +2091,8 @@ export const mockTimelineModel: TimelineModel = { ], dataProviders: [], dateRange: { - end: 1584539558929, - start: 1584539198929, + end: '2020-03-18T13:52:38.929Z', + start: '2020-03-18T13:46:38.929Z', }, deletedEventIds: [], description: 'This is a sample rule description', @@ -2154,7 +2154,7 @@ export const mockTimelineModel: TimelineModel = { export const mockTimelineResult: TimelineResult = { savedObjectId: 'ef579e40-jibber-jabber', columns: timelineDefaults.columns.filter((column) => column.id !== 'event.action'), - dateRange: { start: 1584539198929, end: 1584539558929 }, + dateRange: { start: '2020-03-18T13:46:38.929Z', end: '2020-03-18T13:52:38.929Z' }, description: 'This is a sample rule description', eventType: 'all', filters: [ @@ -2188,7 +2188,7 @@ export const mockTimelineApolloResult = { }; export const defaultTimelineProps: CreateTimelineProps = { - from: 1541444305937, + from: '2018-11-05T18:58:25.937Z', timeline: { columns: [ { columnHeaderType: 'not-filtered', id: '@timestamp', width: 190 }, @@ -2212,7 +2212,7 @@ export const defaultTimelineProps: CreateTimelineProps = { queryMatch: { field: '_id', operator: ':', value: '1' }, }, ], - dateRange: { end: 1541444605937, start: 1541444305937 }, + dateRange: { end: '2018-11-05T19:03:25.937Z', start: '2018-11-05T18:58:25.937Z' }, deletedEventIds: [], description: '', eventIdToNoteIds: {}, @@ -2251,6 +2251,6 @@ export const defaultTimelineProps: CreateTimelineProps = { version: null, width: 1100, }, - to: 1541444605937, + to: '2018-11-05T19:03:25.937Z', ruleNote: '# this is some markdown documentation', }; diff --git a/x-pack/plugins/security_solution/public/common/store/inputs/actions.ts b/x-pack/plugins/security_solution/public/common/store/inputs/actions.ts index f8b8d0865d1203..efad0638b2971b 100644 --- a/x-pack/plugins/security_solution/public/common/store/inputs/actions.ts +++ b/x-pack/plugins/security_solution/public/common/store/inputs/actions.ts @@ -14,21 +14,21 @@ const actionCreator = actionCreatorFactory('x-pack/security_solution/local/input export const setAbsoluteRangeDatePicker = actionCreator<{ id: InputsModelId; - from: number; - to: number; + from: string; + to: string; }>('SET_ABSOLUTE_RANGE_DATE_PICKER'); export const setTimelineRangeDatePicker = actionCreator<{ - from: number; - to: number; + from: string; + to: string; }>('SET_TIMELINE_RANGE_DATE_PICKER'); export const setRelativeRangeDatePicker = actionCreator<{ id: InputsModelId; fromStr: string; toStr: string; - from: number; - to: number; + from: string; + to: string; }>('SET_RELATIVE_RANGE_DATE_PICKER'); export const setDuration = actionCreator<{ id: InputsModelId; duration: number }>('SET_DURATION'); diff --git a/x-pack/plugins/security_solution/public/common/store/inputs/helpers.test.ts b/x-pack/plugins/security_solution/public/common/store/inputs/helpers.test.ts index d23110b44ad434..b54d8ca20b0d1a 100644 --- a/x-pack/plugins/security_solution/public/common/store/inputs/helpers.test.ts +++ b/x-pack/plugins/security_solution/public/common/store/inputs/helpers.test.ts @@ -53,8 +53,8 @@ describe('Inputs', () => { kind: 'relative', fromStr: 'now-48h', toStr: 'now', - from: 23, - to: 26, + from: '2020-07-06T08:00:00.000Z', + to: '2020-07-08T08:00:00.000Z', }; const newState: InputsModel = updateInputTimerange('global', newTimerange, state); expect(newState.timeline.timerange).toEqual(newState.global.timerange); @@ -65,8 +65,8 @@ describe('Inputs', () => { kind: 'relative', fromStr: 'now-68h', toStr: 'NOTnow', - from: 29, - to: 33, + from: '2020-07-05T22:00:00.000Z', + to: '2020-07-08T18:00:00.000Z', }; const newState: InputsModel = updateInputTimerange('timeline', newTimerange, state); expect(newState.timeline.timerange).toEqual(newState.global.timerange); @@ -83,8 +83,8 @@ describe('Inputs', () => { kind: 'relative', fromStr: 'now-48h', toStr: 'now', - from: 23, - to: 26, + from: '2020-07-06T08:00:00.000Z', + to: '2020-07-08T08:00:00.000Z', }; const newState: InputsModel = updateInputTimerange('global', newTimerange, state); expect(newState.timeline.timerange).toEqual(state.timeline.timerange); @@ -96,8 +96,8 @@ describe('Inputs', () => { kind: 'relative', fromStr: 'now-68h', toStr: 'NOTnow', - from: 29, - to: 33, + from: '2020-07-05T22:00:00.000Z', + to: '2020-07-08T18:00:00.000Z', }; const newState: InputsModel = updateInputTimerange('timeline', newTimerange, state); expect(newState.timeline.timerange).toEqual(newTimerange); @@ -274,10 +274,10 @@ describe('Inputs', () => { }, ], timerange: { - from: 0, + from: '2020-07-07T08:20:18.966Z', fromStr: 'now-24h', kind: 'relative', - to: 1, + to: '2020-07-08T08:20:18.966Z', toStr: 'now', }, query: { query: '', language: 'kuery' }, @@ -291,10 +291,10 @@ describe('Inputs', () => { }, queries: [], timerange: { - from: 0, + from: '2020-07-07T08:20:18.966Z', fromStr: 'now-24h', kind: 'relative', - to: 1, + to: '2020-07-08T08:20:18.966Z', toStr: 'now', }, query: { query: '', language: 'kuery' }, diff --git a/x-pack/plugins/security_solution/public/common/store/inputs/model.ts b/x-pack/plugins/security_solution/public/common/store/inputs/model.ts index e851caf523eb4b..358124405c1469 100644 --- a/x-pack/plugins/security_solution/public/common/store/inputs/model.ts +++ b/x-pack/plugins/security_solution/public/common/store/inputs/model.ts @@ -13,16 +13,16 @@ export interface AbsoluteTimeRange { kind: 'absolute'; fromStr: undefined; toStr: undefined; - from: number; - to: number; + from: string; + to: string; } export interface RelativeTimeRange { kind: 'relative'; fromStr: string; toStr: string; - from: number; - to: number; + from: string; + to: string; } export const isRelativeTimeRange = ( @@ -35,10 +35,7 @@ export const isAbsoluteTimeRange = ( export type TimeRange = AbsoluteTimeRange | RelativeTimeRange; -export type URLTimeRange = Omit & { - from: string | TimeRange['from']; - to: string | TimeRange['to']; -}; +export type URLTimeRange = TimeRange; export interface Policy { kind: 'manual' | 'interval'; diff --git a/x-pack/plugins/security_solution/public/common/utils/default_date_settings.test.ts b/x-pack/plugins/security_solution/public/common/utils/default_date_settings.test.ts index 9fc5490b16cab3..c0e009c46a6b66 100644 --- a/x-pack/plugins/security_solution/public/common/utils/default_date_settings.test.ts +++ b/x-pack/plugins/security_solution/public/common/utils/default_date_settings.test.ts @@ -217,38 +217,38 @@ describe('getTimeRangeSettings', () => { test('should return DEFAULT_FROM', () => { mockTimeRange(); const { from } = getTimeRangeSettings(); - expect(from).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); + expect(from).toBe(new Date(DEFAULT_FROM_DATE).toISOString()); }); test('should return a custom from range', () => { const mockFrom = '2019-08-30T17:49:18.396Z'; mockTimeRange({ from: mockFrom }); const { from } = getTimeRangeSettings(); - expect(from).toBe(new Date(mockFrom).valueOf()); + expect(from).toBe(new Date(mockFrom).toISOString()); }); test('should return the DEFAULT_FROM when the whole object is null', () => { mockTimeRange(null); const { from } = getTimeRangeSettings(); - expect(from).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); + expect(from).toBe(new Date(DEFAULT_FROM_DATE).toISOString()); }); test('should return the DEFAULT_FROM when the whole object is undefined', () => { mockTimeRange(null); const { from } = getTimeRangeSettings(); - expect(from).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); + expect(from).toBe(new Date(DEFAULT_FROM_DATE).toISOString()); }); test('should return the DEFAULT_FROM when the from value is null', () => { mockTimeRange({ from: null }); const { from } = getTimeRangeSettings(); - expect(from).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); + expect(from).toBe(new Date(DEFAULT_FROM_DATE).toISOString()); }); test('should return the DEFAULT_FROM when the from value is undefined', () => { mockTimeRange({ from: undefined }); const { from } = getTimeRangeSettings(); - expect(from).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); + expect(from).toBe(new Date(DEFAULT_FROM_DATE).toISOString()); }); test('should return the DEFAULT_FROM when the from value is malformed', () => { @@ -256,7 +256,7 @@ describe('getTimeRangeSettings', () => { if (isMalformedTimeRange(malformedTimeRange)) { mockTimeRange(malformedTimeRange); const { from } = getTimeRangeSettings(); - expect(from).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); + expect(from).toBe(new Date(DEFAULT_FROM_DATE).toISOString()); } else { throw Error('Was expecting an object to be used for the malformed time range'); } @@ -271,7 +271,7 @@ describe('getTimeRangeSettings', () => { it('is DEFAULT_FROM in epoch', () => { const { from } = getTimeRangeSettings(false); - expect(from).toBe(new Date(DEFAULT_FROM_DATE).valueOf()); + expect(from).toBe(new Date(DEFAULT_FROM_DATE).toISOString()); }); }); }); @@ -280,38 +280,38 @@ describe('getTimeRangeSettings', () => { test('should return DEFAULT_TO', () => { mockTimeRange(); const { to } = getTimeRangeSettings(); - expect(to).toBe(new Date(DEFAULT_TO_DATE).valueOf()); + expect(to).toBe(new Date(DEFAULT_TO_DATE).toISOString()); }); test('should return a custom from range', () => { const mockTo = '2000-08-30T17:49:18.396Z'; mockTimeRange({ to: mockTo }); const { to } = getTimeRangeSettings(); - expect(to).toBe(new Date(mockTo).valueOf()); + expect(to).toBe(new Date(mockTo).toISOString()); }); test('should return the DEFAULT_TO_DATE when the whole object is null', () => { mockTimeRange(null); const { to } = getTimeRangeSettings(); - expect(to).toBe(new Date(DEFAULT_TO_DATE).valueOf()); + expect(to).toBe(new Date(DEFAULT_TO_DATE).toISOString()); }); test('should return the DEFAULT_TO_DATE when the whole object is undefined', () => { mockTimeRange(null); const { to } = getTimeRangeSettings(); - expect(to).toBe(new Date(DEFAULT_TO_DATE).valueOf()); + expect(to).toBe(new Date(DEFAULT_TO_DATE).toISOString()); }); test('should return the DEFAULT_TO_DATE when the from value is null', () => { mockTimeRange({ from: null }); const { to } = getTimeRangeSettings(); - expect(to).toBe(new Date(DEFAULT_TO_DATE).valueOf()); + expect(to).toBe(new Date(DEFAULT_TO_DATE).toISOString()); }); test('should return the DEFAULT_TO_DATE when the from value is undefined', () => { mockTimeRange({ from: undefined }); const { to } = getTimeRangeSettings(); - expect(to).toBe(new Date(DEFAULT_TO_DATE).valueOf()); + expect(to).toBe(new Date(DEFAULT_TO_DATE).toISOString()); }); test('should return the DEFAULT_TO_DATE when the from value is malformed', () => { @@ -319,7 +319,7 @@ describe('getTimeRangeSettings', () => { if (isMalformedTimeRange(malformedTimeRange)) { mockTimeRange(malformedTimeRange); const { to } = getTimeRangeSettings(); - expect(to).toBe(new Date(DEFAULT_TO_DATE).valueOf()); + expect(to).toBe(new Date(DEFAULT_TO_DATE).toISOString()); } else { throw Error('Was expecting an object to be used for the malformed time range'); } @@ -334,7 +334,7 @@ describe('getTimeRangeSettings', () => { it('is DEFAULT_TO in epoch', () => { const { to } = getTimeRangeSettings(false); - expect(to).toBe(new Date(DEFAULT_TO_DATE).valueOf()); + expect(to).toBe(new Date(DEFAULT_TO_DATE).toISOString()); }); }); }); @@ -498,12 +498,12 @@ describe('getIntervalSettings', () => { '1930-05-31T13:03:54.234Z', moment('1950-05-31T13:03:54.234Z') ); - expect(value.valueOf()).toBe(new Date('1930-05-31T13:03:54.234Z').valueOf()); + expect(value.toISOString()).toBe(new Date('1930-05-31T13:03:54.234Z').toISOString()); }); test('should return the second value if the first is a bad string', () => { const value = parseDateWithDefault('trashed string', moment('1950-05-31T13:03:54.234Z')); - expect(value.valueOf()).toBe(new Date('1950-05-31T13:03:54.234Z').valueOf()); + expect(value.toISOString()).toBe(new Date('1950-05-31T13:03:54.234Z').toISOString()); }); }); }); diff --git a/x-pack/plugins/security_solution/public/common/utils/default_date_settings.ts b/x-pack/plugins/security_solution/public/common/utils/default_date_settings.ts index b8b4b23e20b859..148143bb00bead 100644 --- a/x-pack/plugins/security_solution/public/common/utils/default_date_settings.ts +++ b/x-pack/plugins/security_solution/public/common/utils/default_date_settings.ts @@ -49,8 +49,8 @@ export const getTimeRangeSettings = (uiSettings = true) => { const fromStr = (isString(timeRange?.from) && timeRange?.from) || DEFAULT_FROM; const toStr = (isString(timeRange?.to) && timeRange?.to) || DEFAULT_TO; - const from = parseDateWithDefault(fromStr, DEFAULT_FROM_MOMENT).valueOf(); - const to = parseDateWithDefault(toStr, DEFAULT_TO_MOMENT).valueOf(); + const from = parseDateWithDefault(fromStr, DEFAULT_FROM_MOMENT).toISOString(); + const to = parseDateWithDefault(toStr, DEFAULT_TO_MOMENT).toISOString(); return { from, fromStr, to, toStr }; }; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/alerts_histogram.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/alerts_histogram.test.tsx index 7f340b0bea37bd..09883e342f998e 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/alerts_histogram.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/alerts_histogram.test.tsx @@ -18,8 +18,8 @@ describe('AlertsHistogram', () => { legendItems={[]} loading={false} data={[]} - from={0} - to={1} + from={'2020-07-07T08:20:18.966Z'} + to={'2020-07-08T08:20:18.966Z'} updateDateRange={jest.fn()} /> ); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/alerts_histogram.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/alerts_histogram.tsx index 11dcbfa39d574e..ffd7f7918ec72b 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/alerts_histogram.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/alerts_histogram.tsx @@ -26,11 +26,11 @@ const DEFAULT_CHART_HEIGHT = 174; interface AlertsHistogramProps { chartHeight?: number; - from: number; + from: string; legendItems: LegendItem[]; legendPosition?: Position; loading: boolean; - to: number; + to: string; data: HistogramData[]; updateDateRange: UpdateDateRange; } diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/helpers.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/helpers.tsx index 9d124201f022e1..0cbed86f18768b 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/helpers.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/helpers.tsx @@ -3,6 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ +import moment from 'moment'; import { showAllOthersBucket } from '../../../../common/constants'; import { HistogramData, AlertsAggregation, AlertsBucket, AlertsGroupBucket } from './types'; @@ -28,8 +29,8 @@ export const formatAlertsData = (alertsData: AlertSearchResponse<{}, AlertsAggre export const getAlertsHistogramQuery = ( stackByField: string, - from: number, - to: number, + from: string, + to: string, additionalFilters: Array<{ bool: { filter: unknown[]; should: unknown[]; must_not: unknown[]; must: unknown[] }; }> @@ -55,7 +56,7 @@ export const getAlertsHistogramQuery = ( alerts: { date_histogram: { field: '@timestamp', - fixed_interval: `${Math.floor((to - from) / 32)}ms`, + fixed_interval: `${Math.floor(moment(to).diff(moment(from)) / 32)}ms`, min_doc_count: 0, extended_bounds: { min: from, diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/index.test.tsx index 59d97480418b79..4cbfa59aac5826 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_histogram_panel/index.test.tsx @@ -40,10 +40,10 @@ jest.mock('../../../common/components/navigation/use_get_url_search'); describe('AlertsHistogramPanel', () => { const defaultProps = { - from: 0, + from: '2020-07-07T08:20:18.966Z', signalIndexName: 'signalIndexName', setQuery: jest.fn(), - to: 1, + to: '2020-07-08T08:20:18.966Z', updateDateRange: jest.fn(), }; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.test.tsx index 24bfeaa4dae1a6..16d1a1481bc968 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.test.tsx @@ -70,7 +70,7 @@ describe('alert actions', () => { updateTimelineIsLoading, }); const expected = { - from: 1541444305937, + from: '2018-11-05T18:58:25.937Z', timeline: { columns: [ { @@ -153,8 +153,8 @@ describe('alert actions', () => { ], dataProviders: [], dateRange: { - end: 1541444605937, - start: 1541444305937, + end: '2018-11-05T19:03:25.937Z', + start: '2018-11-05T18:58:25.937Z', }, deletedEventIds: [], description: 'This is a sample rule description', @@ -225,7 +225,7 @@ describe('alert actions', () => { version: null, width: 1100, }, - to: 1541444605937, + to: '2018-11-05T19:03:25.937Z', ruleNote: '# this is some markdown documentation', }; @@ -375,8 +375,8 @@ describe('alert actions', () => { }; const result = determineToAndFrom({ ecsData: ecsDataMock }); - expect(result.from).toEqual(1584726886349); - expect(result.to).toEqual(1584727186349); + expect(result.from).toEqual('2020-03-20T17:54:46.349Z'); + expect(result.to).toEqual('2020-03-20T17:59:46.349Z'); }); test('it uses current time timestamp if ecsData.timestamp is not provided', () => { @@ -385,8 +385,8 @@ describe('alert actions', () => { }; const result = determineToAndFrom({ ecsData: ecsDataMock }); - expect(result.from).toEqual(1583085286349); - expect(result.to).toEqual(1583085586349); + expect(result.from).toEqual('2020-03-01T17:54:46.349Z'); + expect(result.to).toEqual('2020-03-01T17:59:46.349Z'); }); }); }); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx index 11c13c2358e940..7bebc9efbee157 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx @@ -97,8 +97,8 @@ export const determineToAndFrom = ({ ecsData }: { ecsData: Ecs }) => { const from = moment(ecsData.timestamp ?? new Date()) .subtract(ellapsedTimeRule) - .valueOf(); - const to = moment(ecsData.timestamp ?? new Date()).valueOf(); + .toISOString(); + const to = moment(ecsData.timestamp ?? new Date()).toISOString(); return { to, from }; }; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.test.tsx index f99a0256c0b3fe..563f2ea60cded5 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.test.tsx @@ -19,10 +19,10 @@ describe('AlertsTableComponent', () => { timelineId={TimelineId.test} canUserCRUD hasIndexWrite - from={0} + from={'2020-07-07T08:20:18.966Z'} loading signalsIndex="index" - to={1} + to={'2020-07-08T08:20:18.966Z'} globalQuery={{ query: 'query', language: 'language', diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx index b9b963a84e966f..391598ebda03d6 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx @@ -62,10 +62,10 @@ interface OwnProps { canUserCRUD: boolean; defaultFilters?: Filter[]; hasIndexWrite: boolean; - from: number; + from: string; loading: boolean; signalsIndex: string; - to: number; + to: string; } type AlertsTableComponentProps = OwnProps & PropsFromRedux; diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/types.ts b/x-pack/plugins/security_solution/public/detections/components/alerts_table/types.ts index 34d18b4dedba6e..ebf1a6d3ed533e 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/types.ts +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/types.ts @@ -60,9 +60,9 @@ export interface SendAlertToTimelineActionProps { export type UpdateTimelineLoading = ({ id, isLoading }: { id: string; isLoading: boolean }) => void; export interface CreateTimelineProps { - from: number; + from: string; timeline: TimelineModel; - to: number; + to: string; ruleNote?: string; } diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.test.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.test.tsx index 0204a2980b9fc7..d36c19a6a35c66 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.test.tsx @@ -374,6 +374,16 @@ describe('useFetchIndexPatterns', () => { 'winlogbeat-*', ], indicesExists: true, + docValueFields: [ + { + field: '@timestamp', + format: 'date_time', + }, + { + field: 'event.end', + format: 'date_time', + }, + ], indexPatterns: { fields: [ { name: '@timestamp', searchable: true, type: 'date', aggregatable: true }, @@ -441,6 +451,7 @@ describe('useFetchIndexPatterns', () => { expect(result.current).toEqual([ { browserFields: {}, + docValueFields: [], indexPatterns: { fields: [], title: '', diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.tsx index 640d6f9a17fd13..ab12f045cddbca 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.tsx +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.tsx @@ -12,8 +12,10 @@ import { IIndexPattern } from '../../../../../../../../src/plugins/data/public'; import { BrowserFields, getBrowserFields, + getdocValueFields, getIndexFields, sourceQuery, + DocValueFields, } from '../../../../common/containers/source'; import { errorToToaster, useStateToaster } from '../../../../common/components/toasters'; import { SourceQuery } from '../../../../graphql/types'; @@ -23,6 +25,7 @@ import * as i18n from './translations'; interface FetchIndexPatternReturn { browserFields: BrowserFields; + docValueFields: DocValueFields[]; isLoading: boolean; indices: string[]; indicesExists: boolean; @@ -31,18 +34,29 @@ interface FetchIndexPatternReturn { export type Return = [FetchIndexPatternReturn, Dispatch>]; +const DEFAULT_BROWSER_FIELDS = {}; +const DEFAULT_INDEX_PATTERNS = { fields: [], title: '' }; +const DEFAULT_DOC_VALUE_FIELDS: DocValueFields[] = []; + export const useFetchIndexPatterns = (defaultIndices: string[] = []): Return => { const apolloClient = useApolloClient(); const [indices, setIndices] = useState(defaultIndices); - const [indicesExists, setIndicesExists] = useState(false); - const [indexPatterns, setIndexPatterns] = useState({ fields: [], title: '' }); - const [browserFields, setBrowserFields] = useState({}); - const [isLoading, setIsLoading] = useState(false); + + const [state, setState] = useState({ + browserFields: DEFAULT_BROWSER_FIELDS, + docValueFields: DEFAULT_DOC_VALUE_FIELDS, + indices: defaultIndices, + indicesExists: false, + indexPatterns: DEFAULT_INDEX_PATTERNS, + isLoading: false, + }); + const [, dispatchToaster] = useStateToaster(); useEffect(() => { if (!deepEqual(defaultIndices, indices)) { setIndices(defaultIndices); + setState((prevState) => ({ ...prevState, indices: defaultIndices })); } }, [defaultIndices, indices]); @@ -52,7 +66,7 @@ export const useFetchIndexPatterns = (defaultIndices: string[] = []): Return => async function fetchIndexPatterns() { if (apolloClient && !isEmpty(indices)) { - setIsLoading(true); + setState((prevState) => ({ ...prevState, isLoading: true })); apolloClient .query({ query: sourceQuery, @@ -70,19 +84,28 @@ export const useFetchIndexPatterns = (defaultIndices: string[] = []): Return => .then( (result) => { if (isSubscribed) { - setIsLoading(false); - setIndicesExists(get('data.source.status.indicesExist', result)); - setIndexPatterns( - getIndexFields(indices.join(), get('data.source.status.indexFields', result)) - ); - setBrowserFields( - getBrowserFields(indices.join(), get('data.source.status.indexFields', result)) - ); + setState({ + browserFields: getBrowserFields( + indices.join(), + get('data.source.status.indexFields', result) + ), + docValueFields: getdocValueFields( + indices.join(), + get('data.source.status.indexFields', result) + ), + indices, + isLoading: false, + indicesExists: get('data.source.status.indicesExist', result), + indexPatterns: getIndexFields( + indices.join(), + get('data.source.status.indexFields', result) + ), + }); } }, (error) => { if (isSubscribed) { - setIsLoading(false); + setState((prevState) => ({ ...prevState, isLoading: false })); errorToToaster({ title: i18n.RULE_ADD_FAILURE, error, dispatchToaster }); } } @@ -97,5 +120,5 @@ export const useFetchIndexPatterns = (defaultIndices: string[] = []): Return => // eslint-disable-next-line react-hooks/exhaustive-deps }, [indices]); - return [{ browserFields, isLoading, indices, indicesExists, indexPatterns }, setIndices]; + return [state, setIndices]; }; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.test.tsx index d5aa57ddd87547..f4004a66c8f80c 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.test.tsx @@ -19,9 +19,12 @@ jest.mock('../../components/user_info'); jest.mock('../../../common/containers/source'); jest.mock('../../../common/components/link_to'); jest.mock('../../../common/containers/use_global_time', () => ({ - useGlobalTime: jest - .fn() - .mockReturnValue({ from: 0, isInitializing: false, to: 0, setQuery: jest.fn() }), + useGlobalTime: jest.fn().mockReturnValue({ + from: '2020-07-07T08:20:18.966Z', + isInitializing: false, + to: '2020-07-08T08:20:18.966Z', + setQuery: jest.fn(), + }), })); jest.mock('react-router-dom', () => { const originalModule = jest.requireActual('react-router-dom'); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx index 84cfc744312f91..cdff8ea4ab928a 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx @@ -70,7 +70,11 @@ export const DetectionEnginePageComponent: React.FC = ({ return; } const [min, max] = x; - setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); + setAbsoluteRangeDatePicker({ + id: 'global', + from: new Date(min).toISOString(), + to: new Date(max).toISOString(), + }); }, [setAbsoluteRangeDatePicker] ); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.test.tsx index 0a42602e5fbb28..f4b112d4652605 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.test.tsx @@ -20,9 +20,12 @@ jest.mock('../../../../../common/components/link_to'); jest.mock('../../../../components/user_info'); jest.mock('../../../../../common/containers/source'); jest.mock('../../../../../common/containers/use_global_time', () => ({ - useGlobalTime: jest - .fn() - .mockReturnValue({ from: 0, isInitializing: false, to: 0, setQuery: jest.fn() }), + useGlobalTime: jest.fn().mockReturnValue({ + from: '2020-07-07T08:20:18.966Z', + isInitializing: false, + to: '2020-07-08T08:20:18.966Z', + setQuery: jest.fn(), + }), })); jest.mock('react-router-dom', () => { diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx index c74a2a3cf993a4..45a1c89cec621c 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx @@ -236,7 +236,11 @@ export const RuleDetailsPageComponent: FC = ({ return; } const [min, max] = x; - setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); + setAbsoluteRangeDatePicker({ + id: 'global', + from: new Date(min).toISOString(), + to: new Date(max).toISOString(), + }); }, [setAbsoluteRangeDatePicker] ); diff --git a/x-pack/plugins/security_solution/public/graphql/introspection.json b/x-pack/plugins/security_solution/public/graphql/introspection.json index 4716440c36e61a..4e91324ecc9ffe 100644 --- a/x-pack/plugins/security_solution/public/graphql/introspection.json +++ b/x-pack/plugins/security_solution/public/graphql/introspection.json @@ -735,6 +735,28 @@ } }, "defaultValue": null + }, + { + "name": "docValueFields", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "docValueFieldsInput", + "ofType": null + } + } + } + }, + "defaultValue": null } ], "type": { @@ -816,6 +838,28 @@ } }, "defaultValue": null + }, + { + "name": "docValueFields", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "docValueFieldsInput", + "ofType": null + } + } + } + }, + "defaultValue": null } ], "type": { @@ -867,6 +911,28 @@ } }, "defaultValue": null + }, + { + "name": "docValueFields", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "docValueFieldsInput", + "ofType": null + } + } + } + }, + "defaultValue": null } ], "type": { @@ -924,6 +990,28 @@ } }, "defaultValue": null + }, + { + "name": "docValueFields", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "docValueFieldsInput", + "ofType": null + } + } + } + }, + "defaultValue": null } ], "type": { @@ -1001,6 +1089,28 @@ } }, "defaultValue": null + }, + { + "name": "docValueFields", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "docValueFieldsInput", + "ofType": null + } + } + } + }, + "defaultValue": null } ], "type": { @@ -1105,6 +1215,28 @@ } }, "defaultValue": null + }, + { + "name": "docValueFields", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "docValueFieldsInput", + "ofType": null + } + } + } + }, + "defaultValue": null } ], "type": { @@ -1158,6 +1290,28 @@ } }, "defaultValue": null + }, + { + "name": "docValueFields", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "docValueFieldsInput", + "ofType": null + } + } + } + }, + "defaultValue": null } ], "type": { "kind": "OBJECT", "name": "IpOverviewData", "ofType": null }, @@ -1817,6 +1971,28 @@ "description": "", "type": { "kind": "SCALAR", "name": "String", "ofType": null }, "defaultValue": null + }, + { + "name": "docValueFields", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "docValueFieldsInput", + "ofType": null + } + } + } + }, + "defaultValue": null } ], "type": { @@ -2522,7 +2698,7 @@ "type": { "kind": "NON_NULL", "name": null, - "ofType": { "kind": "SCALAR", "name": "Float", "ofType": null } + "ofType": { "kind": "SCALAR", "name": "String", "ofType": null } }, "defaultValue": null }, @@ -2532,7 +2708,7 @@ "type": { "kind": "NON_NULL", "name": null, - "ofType": { "kind": "SCALAR", "name": "Float", "ofType": null } + "ofType": { "kind": "SCALAR", "name": "String", "ofType": null } }, "defaultValue": null } @@ -2592,6 +2768,37 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "INPUT_OBJECT", + "name": "docValueFieldsInput", + "description": "", + "fields": null, + "inputFields": [ + { + "name": "field", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { "kind": "SCALAR", "name": "String", "ofType": null } + }, + "defaultValue": null + }, + { + "name": "format", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { "kind": "SCALAR", "name": "String", "ofType": null } + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, { "kind": "OBJECT", "name": "AuthenticationsData", @@ -10219,7 +10426,7 @@ "name": "start", "description": "", "args": [], - "type": { "kind": "SCALAR", "name": "Float", "ofType": null }, + "type": { "kind": "SCALAR", "name": "ToAny", "ofType": null }, "isDeprecated": false, "deprecationReason": null }, @@ -10227,7 +10434,7 @@ "name": "end", "description": "", "args": [], - "type": { "kind": "SCALAR", "name": "Float", "ofType": null }, + "type": { "kind": "SCALAR", "name": "ToAny", "ofType": null }, "isDeprecated": false, "deprecationReason": null } @@ -11705,13 +11912,13 @@ { "name": "start", "description": "", - "type": { "kind": "SCALAR", "name": "Float", "ofType": null }, + "type": { "kind": "SCALAR", "name": "ToAny", "ofType": null }, "defaultValue": null }, { "name": "end", "description": "", - "type": { "kind": "SCALAR", "name": "Float", "ofType": null }, + "type": { "kind": "SCALAR", "name": "ToAny", "ofType": null }, "defaultValue": null } ], diff --git a/x-pack/plugins/security_solution/public/graphql/types.ts b/x-pack/plugins/security_solution/public/graphql/types.ts index 98addf3317ff4e..5f8595df23f9bb 100644 --- a/x-pack/plugins/security_solution/public/graphql/types.ts +++ b/x-pack/plugins/security_solution/public/graphql/types.ts @@ -24,9 +24,9 @@ export interface TimerangeInput { /** The interval string to use for last bucket. The format is '{value}{unit}'. For example '5m' would return the metrics for the last 5 minutes of the timespan. */ interval: string; /** The end of the timerange */ - to: number; + to: string; /** The beginning of the timerange */ - from: number; + from: string; } export interface PaginationInputPaginated { @@ -40,6 +40,12 @@ export interface PaginationInputPaginated { querySize: number; } +export interface DocValueFieldsInput { + field: string; + + format: string; +} + export interface PaginationInput { /** The limit parameter allows you to configure the maximum amount of items to be returned */ limit: number; @@ -260,9 +266,9 @@ export interface KueryFilterQueryInput { } export interface DateRangePickerInput { - start?: Maybe; + start?: Maybe; - end?: Maybe; + end?: Maybe; } export interface SortTimelineInput { @@ -2093,9 +2099,9 @@ export interface QueryMatchResult { } export interface DateRangePickerResult { - start?: Maybe; + start?: Maybe; - end?: Maybe; + end?: Maybe; } export interface FavoriteTimelineResult { @@ -2332,6 +2338,8 @@ export interface AuthenticationsSourceArgs { filterQuery?: Maybe; defaultIndex: string[]; + + docValueFields: DocValueFieldsInput[]; } export interface TimelineSourceArgs { pagination: PaginationInput; @@ -2345,6 +2353,8 @@ export interface TimelineSourceArgs { filterQuery?: Maybe; defaultIndex: string[]; + + docValueFields: DocValueFieldsInput[]; } export interface TimelineDetailsSourceArgs { eventId: string; @@ -2352,6 +2362,8 @@ export interface TimelineDetailsSourceArgs { indexName: string; defaultIndex: string[]; + + docValueFields: DocValueFieldsInput[]; } export interface LastEventTimeSourceArgs { id?: Maybe; @@ -2361,6 +2373,8 @@ export interface LastEventTimeSourceArgs { details: LastTimeDetails; defaultIndex: string[]; + + docValueFields: DocValueFieldsInput[]; } export interface HostsSourceArgs { id?: Maybe; @@ -2374,6 +2388,8 @@ export interface HostsSourceArgs { filterQuery?: Maybe; defaultIndex: string[]; + + docValueFields: DocValueFieldsInput[]; } export interface HostOverviewSourceArgs { id?: Maybe; @@ -2390,6 +2406,8 @@ export interface HostFirstLastSeenSourceArgs { hostName: string; defaultIndex: string[]; + + docValueFields: DocValueFieldsInput[]; } export interface IpOverviewSourceArgs { id?: Maybe; @@ -2399,6 +2417,8 @@ export interface IpOverviewSourceArgs { ip: string; defaultIndex: string[]; + + docValueFields: DocValueFieldsInput[]; } export interface UsersSourceArgs { filterQuery?: Maybe; @@ -2514,6 +2534,8 @@ export interface NetworkDnsHistogramSourceArgs { timerange: TimerangeInput; stackByField?: Maybe; + + docValueFields: DocValueFieldsInput[]; } export interface NetworkHttpSourceArgs { id?: Maybe; @@ -2632,6 +2654,7 @@ export namespace GetLastEventTimeQuery { indexKey: LastEventIndexKey; details: LastTimeDetails; defaultIndex: string[]; + docValueFields: DocValueFieldsInput[]; }; export type Query = { @@ -2768,6 +2791,7 @@ export namespace GetAuthenticationsQuery { filterQuery?: Maybe; defaultIndex: string[]; inspect: boolean; + docValueFields: DocValueFieldsInput[]; }; export type Query = { @@ -2904,6 +2928,7 @@ export namespace GetHostFirstLastSeenQuery { sourceId: string; hostName: string; defaultIndex: string[]; + docValueFields: DocValueFieldsInput[]; }; export type Query = { @@ -2938,6 +2963,7 @@ export namespace GetHostsTableQuery { filterQuery?: Maybe; defaultIndex: string[]; inspect: boolean; + docValueFields: DocValueFieldsInput[]; }; export type Query = { @@ -3379,6 +3405,7 @@ export namespace GetIpOverviewQuery { ip: string; defaultIndex: string[]; inspect: boolean; + docValueFields: DocValueFieldsInput[]; }; export type Query = { @@ -4541,6 +4568,7 @@ export namespace GetTimelineDetailsQuery { eventId: string; indexName: string; defaultIndex: string[]; + docValueFields: DocValueFieldsInput[]; }; export type Query = { @@ -4615,6 +4643,8 @@ export namespace GetTimelineQuery { filterQuery?: Maybe; defaultIndex: string[]; inspect: boolean; + docValueFields: DocValueFieldsInput[]; + timerange: TimerangeInput; }; export type Query = { @@ -5644,9 +5674,9 @@ export namespace GetOneTimeline { export type DateRange = { __typename?: 'DateRangePickerResult'; - start: Maybe; + start: Maybe; - end: Maybe; + end: Maybe; }; export type EventIdToNoteIds = { @@ -6030,9 +6060,9 @@ export namespace PersistTimelineMutation { export type DateRange = { __typename?: 'DateRangePickerResult'; - start: Maybe; + start: Maybe; - end: Maybe; + end: Maybe; }; export type Sort = { diff --git a/x-pack/plugins/security_solution/public/hosts/components/kpi_hosts/index.test.tsx b/x-pack/plugins/security_solution/public/hosts/components/kpi_hosts/index.test.tsx index 09e253ae56747d..978bdcaa2bb019 100644 --- a/x-pack/plugins/security_solution/public/hosts/components/kpi_hosts/index.test.tsx +++ b/x-pack/plugins/security_solution/public/hosts/components/kpi_hosts/index.test.tsx @@ -14,8 +14,8 @@ import { kpiHostDetailsMapping } from './kpi_host_details_mapping'; describe('kpiHostsComponent', () => { const ID = 'kpiHost'; - const from = new Date('2019-06-15T06:00:00.000Z').valueOf(); - const to = new Date('2019-06-18T06:00:00.000Z').valueOf(); + const from = '2019-06-15T06:00:00.000Z'; + const to = '2019-06-18T06:00:00.000Z'; const narrowDateRange = () => {}; describe('render', () => { test('it should render spinner if it is loading', () => { diff --git a/x-pack/plugins/security_solution/public/hosts/components/kpi_hosts/index.tsx b/x-pack/plugins/security_solution/public/hosts/components/kpi_hosts/index.tsx index ba70df7d361d45..c39e86591013f9 100644 --- a/x-pack/plugins/security_solution/public/hosts/components/kpi_hosts/index.tsx +++ b/x-pack/plugins/security_solution/public/hosts/components/kpi_hosts/index.tsx @@ -21,10 +21,10 @@ import { UpdateDateRange } from '../../../common/components/charts/common'; const kpiWidgetHeight = 247; interface GenericKpiHostProps { - from: number; + from: string; id: string; loading: boolean; - to: number; + to: string; narrowDateRange: UpdateDateRange; } diff --git a/x-pack/plugins/security_solution/public/hosts/containers/authentications/index.gql_query.ts b/x-pack/plugins/security_solution/public/hosts/containers/authentications/index.gql_query.ts index eee35730cfdbbf..c68816b34c175b 100644 --- a/x-pack/plugins/security_solution/public/hosts/containers/authentications/index.gql_query.ts +++ b/x-pack/plugins/security_solution/public/hosts/containers/authentications/index.gql_query.ts @@ -14,6 +14,7 @@ export const authenticationsQuery = gql` $filterQuery: String $defaultIndex: [String!]! $inspect: Boolean! + $docValueFields: [docValueFieldsInput!]! ) { source(id: $sourceId) { id @@ -22,6 +23,7 @@ export const authenticationsQuery = gql` pagination: $pagination filterQuery: $filterQuery defaultIndex: $defaultIndex + docValueFields: $docValueFields ) { totalCount edges { diff --git a/x-pack/plugins/security_solution/public/hosts/containers/authentications/index.tsx b/x-pack/plugins/security_solution/public/hosts/containers/authentications/index.tsx index bfada0583f8e95..efd80c5c590ed6 100644 --- a/x-pack/plugins/security_solution/public/hosts/containers/authentications/index.tsx +++ b/x-pack/plugins/security_solution/public/hosts/containers/authentications/index.tsx @@ -63,6 +63,7 @@ class AuthenticationsComponentQuery extends QueryTemplatePaginated< const { activePage, children, + docValueFields, endDate, filterQuery, id = ID, @@ -84,6 +85,7 @@ class AuthenticationsComponentQuery extends QueryTemplatePaginated< filterQuery: createFilter(filterQuery), defaultIndex: kibana.services.uiSettings.get(DEFAULT_INDEX_KEY), inspect: isInspected, + docValueFields: docValueFields ?? [], }; return ( diff --git a/x-pack/plugins/security_solution/public/hosts/containers/hosts/first_last_seen/first_last_seen.gql_query.ts b/x-pack/plugins/security_solution/public/hosts/containers/hosts/first_last_seen/first_last_seen.gql_query.ts index 7db4f138c77944..18cbcf516839f1 100644 --- a/x-pack/plugins/security_solution/public/hosts/containers/hosts/first_last_seen/first_last_seen.gql_query.ts +++ b/x-pack/plugins/security_solution/public/hosts/containers/hosts/first_last_seen/first_last_seen.gql_query.ts @@ -7,10 +7,19 @@ import gql from 'graphql-tag'; export const HostFirstLastSeenGqlQuery = gql` - query GetHostFirstLastSeenQuery($sourceId: ID!, $hostName: String!, $defaultIndex: [String!]!) { + query GetHostFirstLastSeenQuery( + $sourceId: ID! + $hostName: String! + $defaultIndex: [String!]! + $docValueFields: [docValueFieldsInput!]! + ) { source(id: $sourceId) { id - HostFirstLastSeen(hostName: $hostName, defaultIndex: $defaultIndex) { + HostFirstLastSeen( + hostName: $hostName + defaultIndex: $defaultIndex + docValueFields: $docValueFields + ) { firstSeen lastSeen } diff --git a/x-pack/plugins/security_solution/public/hosts/containers/hosts/first_last_seen/index.ts b/x-pack/plugins/security_solution/public/hosts/containers/hosts/first_last_seen/index.ts index a4f8fca23e8aa2..65e379b5ba2d82 100644 --- a/x-pack/plugins/security_solution/public/hosts/containers/hosts/first_last_seen/index.ts +++ b/x-pack/plugins/security_solution/public/hosts/containers/hosts/first_last_seen/index.ts @@ -13,7 +13,7 @@ import { useUiSetting$ } from '../../../../common/lib/kibana'; import { GetHostFirstLastSeenQuery } from '../../../../graphql/types'; import { inputsModel } from '../../../../common/store'; import { QueryTemplateProps } from '../../../../common/containers/query_template'; - +import { useWithSource } from '../../../../common/containers/source'; import { HostFirstLastSeenGqlQuery } from './first_last_seen.gql_query'; export interface FirstLastSeenHostArgs { @@ -40,6 +40,7 @@ export function useFirstLastSeenHostQuery( const [lastSeen, updateLastSeen] = useState(null); const [errorMessage, updateErrorMessage] = useState(null); const [defaultIndex] = useUiSetting$(DEFAULT_INDEX_KEY); + const { docValueFields } = useWithSource(sourceId); async function fetchFirstLastSeenHost(signal: AbortSignal) { updateLoading(true); @@ -51,6 +52,7 @@ export function useFirstLastSeenHostQuery( sourceId, hostName, defaultIndex, + docValueFields, }, context: { fetchOptions: { diff --git a/x-pack/plugins/security_solution/public/hosts/containers/hosts/first_last_seen/mock.ts b/x-pack/plugins/security_solution/public/hosts/containers/hosts/first_last_seen/mock.ts index 51e484ffbd8599..7f1b3d97eb5255 100644 --- a/x-pack/plugins/security_solution/public/hosts/containers/hosts/first_last_seen/mock.ts +++ b/x-pack/plugins/security_solution/public/hosts/containers/hosts/first_last_seen/mock.ts @@ -35,6 +35,7 @@ export const mockFirstLastSeenHostQuery: MockedProvidedQuery[] = [ sourceId: 'default', hostName: 'kibana-siem', defaultIndex: DEFAULT_INDEX_PATTERN, + docValueFields: [], }, }, result: { diff --git a/x-pack/plugins/security_solution/public/hosts/containers/hosts/hosts_table.gql_query.ts b/x-pack/plugins/security_solution/public/hosts/containers/hosts/hosts_table.gql_query.ts index 672ea70b09ad21..e93f3e379b30e6 100644 --- a/x-pack/plugins/security_solution/public/hosts/containers/hosts/hosts_table.gql_query.ts +++ b/x-pack/plugins/security_solution/public/hosts/containers/hosts/hosts_table.gql_query.ts @@ -15,6 +15,7 @@ export const HostsTableQuery = gql` $filterQuery: String $defaultIndex: [String!]! $inspect: Boolean! + $docValueFields: [docValueFieldsInput!]! ) { source(id: $sourceId) { id @@ -24,6 +25,7 @@ export const HostsTableQuery = gql` sort: $sort filterQuery: $filterQuery defaultIndex: $defaultIndex + docValueFields: $docValueFields ) { totalCount edges { diff --git a/x-pack/plugins/security_solution/public/hosts/containers/hosts/index.tsx b/x-pack/plugins/security_solution/public/hosts/containers/hosts/index.tsx index 70f21b6f23cc0d..8af24e6e6abc1f 100644 --- a/x-pack/plugins/security_solution/public/hosts/containers/hosts/index.tsx +++ b/x-pack/plugins/security_solution/public/hosts/containers/hosts/index.tsx @@ -33,7 +33,7 @@ import { generateTablePaginationOptions } from '../../../common/components/pagin const ID = 'hostsQuery'; export interface HostsArgs { - endDate: number; + endDate: string; hosts: HostsEdges[]; id: string; inspect: inputsModel.InspectQuery; @@ -42,15 +42,15 @@ export interface HostsArgs { loadPage: (newActivePage: number) => void; pageInfo: PageInfoPaginated; refetch: inputsModel.Refetch; - startDate: number; + startDate: string; totalCount: number; } export interface OwnProps extends QueryTemplatePaginatedProps { children: (args: HostsArgs) => React.ReactNode; type: hostsModel.HostsType; - startDate: number; - endDate: number; + startDate: string; + endDate: string; } export interface HostsComponentReduxProps { @@ -81,6 +81,7 @@ class HostsComponentQuery extends QueryTemplatePaginated< public render() { const { activePage, + docValueFields, id = ID, isInspected, children, @@ -110,6 +111,7 @@ class HostsComponentQuery extends QueryTemplatePaginated< pagination: generateTablePaginationOptions(activePage, limit), filterQuery: createFilter(filterQuery), defaultIndex, + docValueFields: docValueFields ?? [], inspect: isInspected, }; return ( diff --git a/x-pack/plugins/security_solution/public/hosts/containers/hosts/overview/index.tsx b/x-pack/plugins/security_solution/public/hosts/containers/hosts/overview/index.tsx index 5267fff3a26d67..12a82c7980b61b 100644 --- a/x-pack/plugins/security_solution/public/hosts/containers/hosts/overview/index.tsx +++ b/x-pack/plugins/security_solution/public/hosts/containers/hosts/overview/index.tsx @@ -27,8 +27,8 @@ export interface HostOverviewArgs { hostOverview: HostItem; loading: boolean; refetch: inputsModel.Refetch; - startDate: number; - endDate: number; + startDate: string; + endDate: string; } export interface HostOverviewReduxProps { @@ -38,8 +38,8 @@ export interface HostOverviewReduxProps { export interface OwnProps extends QueryTemplateProps { children: (args: HostOverviewArgs) => React.ReactNode; hostName: string; - startDate: number; - endDate: number; + startDate: string; + endDate: string; } type HostsOverViewProps = OwnProps & HostOverviewReduxProps & WithKibanaProps; diff --git a/x-pack/plugins/security_solution/public/hosts/pages/details/details_tabs.test.tsx b/x-pack/plugins/security_solution/public/hosts/pages/details/details_tabs.test.tsx index cce48a1e605b26..08fe48c0dd709d 100644 --- a/x-pack/plugins/security_solution/public/hosts/pages/details/details_tabs.test.tsx +++ b/x-pack/plugins/security_solution/public/hosts/pages/details/details_tabs.test.tsx @@ -17,14 +17,19 @@ import { type } from './utils'; import { useMountAppended } from '../../../common/utils/use_mount_appended'; import { getHostDetailsPageFilters } from './helpers'; +jest.mock('../../../common/components/url_state/normalize_time_range.ts'); + jest.mock('../../../common/containers/source', () => ({ useWithSource: jest.fn().mockReturnValue({ indicesExist: true, indexPattern: mockIndexPattern }), })); jest.mock('../../../common/containers/use_global_time', () => ({ - useGlobalTime: jest - .fn() - .mockReturnValue({ from: 0, isInitializing: false, to: 0, setQuery: jest.fn() }), + useGlobalTime: jest.fn().mockReturnValue({ + from: '2020-07-07T08:20:18.966Z', + isInitializing: false, + to: '2020-07-08T08:20:18.966Z', + setQuery: jest.fn(), + }), })); // Test will fail because we will to need to mock some core services to make the test work @@ -73,17 +78,17 @@ describe('body', () => { @@ -91,10 +96,10 @@ describe('body', () => { // match against everything but the functions to ensure they are there as expected expect(wrapper.find(componentName).props()).toMatchObject({ - endDate: 0, + endDate: '2020-07-08T08:20:18.966Z', filterQuery, skip: false, - startDate: 0, + startDate: '2020-07-07T08:20:18.966Z', type: 'details', indexPattern: { fields: [ diff --git a/x-pack/plugins/security_solution/public/hosts/pages/details/details_tabs.tsx b/x-pack/plugins/security_solution/public/hosts/pages/details/details_tabs.tsx index acde0cbe1d42b7..4d4eead0e778aa 100644 --- a/x-pack/plugins/security_solution/public/hosts/pages/details/details_tabs.tsx +++ b/x-pack/plugins/security_solution/public/hosts/pages/details/details_tabs.tsx @@ -28,6 +28,7 @@ import { export const HostDetailsTabs = React.memo( ({ + docValueFields, pageFilters, filterQuery, detailName, @@ -54,7 +55,11 @@ export const HostDetailsTabs = React.memo( return; } const [min, max] = x; - setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); + setAbsoluteRangeDatePicker({ + id: 'global', + from: new Date(min).toISOString(), + to: new Date(max).toISOString(), + }); }, [setAbsoluteRangeDatePicker] ); @@ -76,7 +81,7 @@ export const HostDetailsTabs = React.memo( return ( - + diff --git a/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx b/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx index bb0317f0482b03..447d003625c8f0 100644 --- a/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx +++ b/x-pack/plugins/security_solution/public/hosts/pages/details/index.tsx @@ -73,11 +73,15 @@ const HostDetailsComponent = React.memo( return; } const [min, max] = x; - setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); + setAbsoluteRangeDatePicker({ + id: 'global', + from: new Date(min).toISOString(), + to: new Date(max).toISOString(), + }); }, [setAbsoluteRangeDatePicker] ); - const { indicesExist, indexPattern } = useWithSource(); + const { docValueFields, indicesExist, indexPattern } = useWithSource(); const filterQuery = convertToBuildEsQuery({ config: esQuery.getEsQueryConfig(kibana.services.uiSettings), indexPattern, @@ -175,6 +179,7 @@ const HostDetailsComponent = React.memo( ; detailName: string; hostDetailsPagePath: string; @@ -56,6 +57,7 @@ export type HostDetailsNavTab = Record; export type HostDetailsTabsProps = HostBodyComponentDispatchProps & HostsQueryProps & { + docValueFields?: DocValueFields[]; pageFilters?: Filter[]; filterQuery: string; indexPattern: IIndexPattern; @@ -64,6 +66,6 @@ export type HostDetailsTabsProps = HostBodyComponentDispatchProps & export type SetAbsoluteRangeDatePicker = ActionCreator<{ id: InputsModelId; - from: number; - to: number; + from: string; + to: string; }>; diff --git a/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx b/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx index a2f83bf0965f36..b37d91cc2be3b0 100644 --- a/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx +++ b/x-pack/plugins/security_solution/public/hosts/pages/hosts.tsx @@ -62,11 +62,15 @@ export const HostsComponent = React.memo( return; } const [min, max] = x; - setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); + setAbsoluteRangeDatePicker({ + id: 'global', + from: new Date(min).toISOString(), + to: new Date(max).toISOString(), + }); }, [setAbsoluteRangeDatePicker] ); - const { indicesExist, indexPattern } = useWithSource(); + const { docValueFields, indicesExist, indexPattern } = useWithSource(); const filterQuery = convertToBuildEsQuery({ config: esQuery.getEsQueryConfig(kibana.services.uiSettings), indexPattern, @@ -125,6 +129,7 @@ export const HostsComponent = React.memo( ( ({ deleteQuery, + docValueFields, filterQuery, setAbsoluteRangeDatePicker, to, @@ -62,7 +63,11 @@ export const HostsTabs = memo( return; } const [min, max] = x; - setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); + setAbsoluteRangeDatePicker({ + id: 'global', + from: new Date(min).toISOString(), + to: new Date(max).toISOString(), + }); }, [setAbsoluteRangeDatePicker] ), @@ -71,10 +76,10 @@ export const HostsTabs = memo( return ( - + - + diff --git a/x-pack/plugins/security_solution/public/hosts/pages/navigation/authentications_query_tab_body.tsx b/x-pack/plugins/security_solution/public/hosts/pages/navigation/authentications_query_tab_body.tsx index 41f5b7816205e8..88886a874a9494 100644 --- a/x-pack/plugins/security_solution/public/hosts/pages/navigation/authentications_query_tab_body.tsx +++ b/x-pack/plugins/security_solution/public/hosts/pages/navigation/authentications_query_tab_body.tsx @@ -61,6 +61,7 @@ const histogramConfigs: MatrixHisrogramConfigs = { export const AuthenticationsQueryTabBody = ({ deleteQuery, + docValueFields, endDate, filterQuery, skip, @@ -89,6 +90,7 @@ export const AuthenticationsQueryTabBody = ({ {...histogramConfigs} /> ( ; }; diff --git a/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map.test.tsx b/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map.test.tsx index 76e197063fb8a3..d7e9d86916c6dd 100644 --- a/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map.test.tsx +++ b/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map.test.tsx @@ -26,11 +26,11 @@ describe('EmbeddedMapComponent', () => { test('renders correctly against snapshot', () => { const wrapper = shallow( ); expect(wrapper).toMatchSnapshot(); diff --git a/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map.tsx b/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map.tsx index 81aa4b1671fcaa..828e4d3eaaaa05 100644 --- a/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map.tsx +++ b/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map.tsx @@ -71,8 +71,8 @@ EmbeddableMap.displayName = 'EmbeddableMap'; export interface EmbeddedMapProps { query: Query; filters: Filter[]; - startDate: number; - endDate: number; + startDate: string; + endDate: string; setQuery: GlobalTimeArgs['setQuery']; } diff --git a/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map_helpers.test.tsx b/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map_helpers.test.tsx index 50170f4f6ae9e4..0c6b90ec2b9ddd 100644 --- a/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map_helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/network/components/embeddables/embedded_map_helpers.test.tsx @@ -35,8 +35,8 @@ describe('embedded_map_helpers', () => { [], [], { query: '', language: 'kuery' }, - 0, - 0, + '2020-07-07T08:20:18.966Z', + '2020-07-08T08:20:18.966Z', setQueryMock, createPortalNode(), mockEmbeddable @@ -50,8 +50,8 @@ describe('embedded_map_helpers', () => { [], [], { query: '', language: 'kuery' }, - 0, - 0, + '2020-07-07T08:20:18.966Z', + '2020-07-08T08:20:18.966Z', setQueryMock, createPortalNode(), mockEmbeddable diff --git a/x-pack/plugins/security_solution/public/network/components/ip_overview/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/network/components/ip_overview/__snapshots__/index.test.tsx.snap index fe34c584bafb7e..ca2ce4ee921c70 100644 --- a/x-pack/plugins/security_solution/public/network/components/ip_overview/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/network/components/ip_overview/__snapshots__/index.test.tsx.snap @@ -137,14 +137,14 @@ exports[`IP Overview Component rendering it renders the default IP Overview 1`] "interval": "day", } } - endDate={1560837600000} + endDate="2019-06-18T06:00:00.000Z" flowTarget="source" id="ipOverview" ip="10.10.10.10" isLoadingAnomaliesData={false} loading={false} narrowDateRange={[MockFunction]} - startDate={1560578400000} + startDate="2019-06-15T06:00:00.000Z" type="details" updateFlowTargetAction={[MockFunction]} /> diff --git a/x-pack/plugins/security_solution/public/network/components/ip_overview/index.test.tsx b/x-pack/plugins/security_solution/public/network/components/ip_overview/index.test.tsx index b8d97f06bf85f8..b9d9279ae34f81 100644 --- a/x-pack/plugins/security_solution/public/network/components/ip_overview/index.test.tsx +++ b/x-pack/plugins/security_solution/public/network/components/ip_overview/index.test.tsx @@ -51,14 +51,14 @@ describe('IP Overview Component', () => { const mockProps = { anomaliesData: mockAnomalies, data: mockData.IpOverview, - endDate: new Date('2019-06-18T06:00:00.000Z').valueOf(), + endDate: '2019-06-18T06:00:00.000Z', flowTarget: FlowTarget.source, loading: false, id: 'ipOverview', ip: '10.10.10.10', isLoadingAnomaliesData: false, narrowDateRange: (jest.fn() as unknown) as NarrowDateRange, - startDate: new Date('2019-06-15T06:00:00.000Z').valueOf(), + startDate: '2019-06-15T06:00:00.000Z', type: networkModel.NetworkType.details, updateFlowTargetAction: (jest.fn() as unknown) as ActionCreator<{ flowTarget: FlowTarget; diff --git a/x-pack/plugins/security_solution/public/network/components/ip_overview/index.tsx b/x-pack/plugins/security_solution/public/network/components/ip_overview/index.tsx index 56f6d27dc28ca4..cf08b084d21979 100644 --- a/x-pack/plugins/security_solution/public/network/components/ip_overview/index.tsx +++ b/x-pack/plugins/security_solution/public/network/components/ip_overview/index.tsx @@ -42,8 +42,8 @@ interface OwnProps { loading: boolean; isLoadingAnomaliesData: boolean; anomaliesData: Anomalies | null; - startDate: number; - endDate: number; + startDate: string; + endDate: string; type: networkModel.NetworkType; narrowDateRange: NarrowDateRange; } diff --git a/x-pack/plugins/security_solution/public/network/components/kpi_network/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/network/components/kpi_network/__snapshots__/index.test.tsx.snap index ee7649b00aed18..2f97e45b217f3f 100644 --- a/x-pack/plugins/security_solution/public/network/components/kpi_network/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/network/components/kpi_network/__snapshots__/index.test.tsx.snap @@ -32,11 +32,11 @@ exports[`KpiNetwork Component rendering it renders loading icons 1`] = ` ], } } - from={1560578400000} + from="2019-06-15T06:00:00.000Z" id="kpiNetwork" loading={true} narrowDateRange={[MockFunction]} - to={1560837600000} + to="2019-06-18T06:00:00.000Z" /> `; @@ -72,10 +72,10 @@ exports[`KpiNetwork Component rendering it renders the default widget 1`] = ` ], } } - from={1560578400000} + from="2019-06-15T06:00:00.000Z" id="kpiNetwork" loading={false} narrowDateRange={[MockFunction]} - to={1560837600000} + to="2019-06-18T06:00:00.000Z" /> `; diff --git a/x-pack/plugins/security_solution/public/network/components/kpi_network/index.test.tsx b/x-pack/plugins/security_solution/public/network/components/kpi_network/index.test.tsx index 8acd17d2ce7676..06f623e61c2809 100644 --- a/x-pack/plugins/security_solution/public/network/components/kpi_network/index.test.tsx +++ b/x-pack/plugins/security_solution/public/network/components/kpi_network/index.test.tsx @@ -21,8 +21,8 @@ import { mockData } from './mock'; describe('KpiNetwork Component', () => { const state: State = mockGlobalState; - const from = new Date('2019-06-15T06:00:00.000Z').valueOf(); - const to = new Date('2019-06-18T06:00:00.000Z').valueOf(); + const from = '2019-06-15T06:00:00.000Z'; + const to = '2019-06-18T06:00:00.000Z'; const narrowDateRange = jest.fn(); const { storage } = createSecuritySolutionStorageMock(); diff --git a/x-pack/plugins/security_solution/public/network/components/kpi_network/index.tsx b/x-pack/plugins/security_solution/public/network/components/kpi_network/index.tsx index ac7381160515d8..dd8979bc02a615 100644 --- a/x-pack/plugins/security_solution/public/network/components/kpi_network/index.tsx +++ b/x-pack/plugins/security_solution/public/network/components/kpi_network/index.tsx @@ -37,10 +37,10 @@ const euiColorVis3 = euiVisColorPalette[3]; interface KpiNetworkProps { data: KpiNetworkData; - from: number; + from: string; id: string; loading: boolean; - to: number; + to: string; narrowDateRange: UpdateDateRange; } @@ -132,8 +132,8 @@ export const KpiNetworkBaseComponent = React.memo<{ fieldsMapping: Readonly; data: KpiNetworkData; id: string; - from: number; - to: number; + from: string; + to: string; narrowDateRange: UpdateDateRange; }>(({ fieldsMapping, data, id, from, to, narrowDateRange }) => { const statItemsProps: StatItemsProps[] = useKpiMatrixStatus( diff --git a/x-pack/plugins/security_solution/public/network/components/kpi_network/mock.ts b/x-pack/plugins/security_solution/public/network/components/kpi_network/mock.ts index a8b04ff29f4b67..bd820d4ed367d5 100644 --- a/x-pack/plugins/security_solution/public/network/components/kpi_network/mock.ts +++ b/x-pack/plugins/security_solution/public/network/components/kpi_network/mock.ts @@ -220,11 +220,11 @@ export const mockEnableChartsData = { icon: 'visMapCoordinate', }, ], - from: 1560578400000, + from: '2019-06-15T06:00:00.000Z', grow: 2, id: 'statItem', index: 2, statKey: 'UniqueIps', - to: 1560837600000, + to: '2019-06-18T06:00:00.000Z', narrowDateRange: mockNarrowDateRange, }; diff --git a/x-pack/plugins/security_solution/public/network/containers/ip_overview/index.gql_query.ts b/x-pack/plugins/security_solution/public/network/containers/ip_overview/index.gql_query.ts index 3733cd780a4f76..6ebb60ccb4ea6b 100644 --- a/x-pack/plugins/security_solution/public/network/containers/ip_overview/index.gql_query.ts +++ b/x-pack/plugins/security_solution/public/network/containers/ip_overview/index.gql_query.ts @@ -13,10 +13,16 @@ export const ipOverviewQuery = gql` $ip: String! $defaultIndex: [String!]! $inspect: Boolean! + $docValueFields: [docValueFieldsInput!]! ) { source(id: $sourceId) { id - IpOverview(filterQuery: $filterQuery, ip: $ip, defaultIndex: $defaultIndex) { + IpOverview( + filterQuery: $filterQuery + ip: $ip + defaultIndex: $defaultIndex + docValueFields: $docValueFields + ) { source { firstSeen lastSeen diff --git a/x-pack/plugins/security_solution/public/network/containers/ip_overview/index.tsx b/x-pack/plugins/security_solution/public/network/containers/ip_overview/index.tsx index 551ecebf2c05a7..6c8b54cc795178 100644 --- a/x-pack/plugins/security_solution/public/network/containers/ip_overview/index.tsx +++ b/x-pack/plugins/security_solution/public/network/containers/ip_overview/index.tsx @@ -35,7 +35,7 @@ export interface IpOverviewProps extends QueryTemplateProps { } const IpOverviewComponentQuery = React.memo( - ({ id = ID, isInspected, children, filterQuery, skip, sourceId, ip }) => ( + ({ id = ID, docValueFields, isInspected, children, filterQuery, skip, sourceId, ip }) => ( query={ipOverviewQuery} fetchPolicy={getDefaultFetchPolicy()} @@ -46,6 +46,7 @@ const IpOverviewComponentQuery = React.memo( filterQuery: createFilter(filterQuery), ip, defaultIndex: useUiSetting(DEFAULT_INDEX_KEY), + docValueFields: docValueFields ?? [], inspect: isInspected, }} > diff --git a/x-pack/plugins/security_solution/public/network/containers/tls/index.tsx b/x-pack/plugins/security_solution/public/network/containers/tls/index.tsx index a50f2a131b75b8..17506f9a01cb92 100644 --- a/x-pack/plugins/security_solution/public/network/containers/tls/index.tsx +++ b/x-pack/plugins/security_solution/public/network/containers/tls/index.tsx @@ -92,8 +92,8 @@ class TlsComponentQuery extends QueryTemplatePaginated< sourceId, timerange: { interval: '12h', - from: startDate ? startDate : 0, - to: endDate ? endDate : Date.now(), + from: startDate ? startDate : '', + to: endDate ? endDate : new Date(Date.now()).toISOString(), }, }; return ( diff --git a/x-pack/plugins/security_solution/public/network/pages/ip_details/index.test.tsx b/x-pack/plugins/security_solution/public/network/pages/ip_details/index.test.tsx index 92f39228f07a75..e2e458bcec2f54 100644 --- a/x-pack/plugins/security_solution/public/network/pages/ip_details/index.test.tsx +++ b/x-pack/plugins/security_solution/public/network/pages/ip_details/index.test.tsx @@ -34,9 +34,12 @@ type GlobalWithFetch = NodeJS.Global & { fetch: jest.Mock }; jest.mock('../../../common/lib/kibana'); jest.mock('../../../common/containers/source'); jest.mock('../../../common/containers/use_global_time', () => ({ - useGlobalTime: jest - .fn() - .mockReturnValue({ from: 0, isInitializing: false, to: 0, setQuery: jest.fn() }), + useGlobalTime: jest.fn().mockReturnValue({ + from: '2020-07-07T08:20:18.966Z', + isInitializing: false, + to: '2020-07-08T08:20:18.966Z', + setQuery: jest.fn(), + }), })); // Test will fail because we will to need to mock some core services to make the test work @@ -67,8 +70,8 @@ const getMockHistory = (ip: string) => ({ listen: jest.fn(), }); -const to = new Date('2018-03-23T18:49:23.132Z').valueOf(); -const from = new Date('2018-03-24T03:33:52.253Z').valueOf(); +const to = '2018-03-23T18:49:23.132Z'; +const from = '2018-03-24T03:33:52.253Z'; const getMockProps = (ip: string) => ({ to, from, @@ -88,8 +91,8 @@ const getMockProps = (ip: string) => ({ match: { params: { detailName: ip, search: '' }, isExact: true, path: '', url: '' }, setAbsoluteRangeDatePicker: (jest.fn() as unknown) as ActionCreator<{ id: InputsModelId; - from: number; - to: number; + from: string; + to: string; }>, setIpDetailsTablesActivePageToZero: (jest.fn() as unknown) as ActionCreator, }); diff --git a/x-pack/plugins/security_solution/public/network/pages/ip_details/index.tsx b/x-pack/plugins/security_solution/public/network/pages/ip_details/index.tsx index 5eb7a1cec67608..e06f5489a3fc2f 100644 --- a/x-pack/plugins/security_solution/public/network/pages/ip_details/index.tsx +++ b/x-pack/plugins/security_solution/public/network/pages/ip_details/index.tsx @@ -77,7 +77,7 @@ export const IPDetailsComponent: React.FC ( return; } const [min, max] = x; - setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); + setAbsoluteRangeDatePicker({ + id: 'global', + from: new Date(min).toISOString(), + to: new Date(max).toISOString(), + }); }, [setAbsoluteRangeDatePicker] ); diff --git a/x-pack/plugins/security_solution/public/network/pages/navigation/types.ts b/x-pack/plugins/security_solution/public/network/pages/navigation/types.ts index 6986d10ad35233..183c760e40ab10 100644 --- a/x-pack/plugins/security_solution/public/network/pages/navigation/types.ts +++ b/x-pack/plugins/security_solution/public/network/pages/navigation/types.ts @@ -18,8 +18,8 @@ import { NarrowDateRange } from '../../../common/components/ml/types'; interface QueryTabBodyProps extends Pick { skip: boolean; type: networkModel.NetworkType; - startDate: number; - endDate: number; + startDate: string; + endDate: string; filterQuery?: string | ESTermQuery; narrowDateRange?: NarrowDateRange; } diff --git a/x-pack/plugins/security_solution/public/network/pages/network.test.tsx b/x-pack/plugins/security_solution/public/network/pages/network.test.tsx index af84e1d42b45b9..78521a980de402 100644 --- a/x-pack/plugins/security_solution/public/network/pages/network.test.tsx +++ b/x-pack/plugins/security_solution/public/network/pages/network.test.tsx @@ -58,8 +58,8 @@ const mockHistory = { listen: jest.fn(), }; -const to = new Date('2018-03-23T18:49:23.132Z').valueOf(); -const from = new Date('2018-03-24T03:33:52.253Z').valueOf(); +const to = '2018-03-23T18:49:23.132Z'; +const from = '2018-03-24T03:33:52.253Z'; const getMockProps = () => ({ networkPagePath: '', diff --git a/x-pack/plugins/security_solution/public/network/pages/network.tsx b/x-pack/plugins/security_solution/public/network/pages/network.tsx index 5767951f9f6b31..f8927096c1a614 100644 --- a/x-pack/plugins/security_solution/public/network/pages/network.tsx +++ b/x-pack/plugins/security_solution/public/network/pages/network.tsx @@ -68,7 +68,11 @@ const NetworkComponent = React.memo( return; } const [min, max] = x; - setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); + setAbsoluteRangeDatePicker({ + id: 'global', + from: new Date(min).toISOString(), + to: new Date(max).toISOString(), + }); }, [setAbsoluteRangeDatePicker] ); diff --git a/x-pack/plugins/security_solution/public/network/pages/types.ts b/x-pack/plugins/security_solution/public/network/pages/types.ts index 54ff5a8d50b8e8..db3546409c8d94 100644 --- a/x-pack/plugins/security_solution/public/network/pages/types.ts +++ b/x-pack/plugins/security_solution/public/network/pages/types.ts @@ -10,8 +10,8 @@ import { InputsModelId } from '../../common/store/inputs/constants'; export type SetAbsoluteRangeDatePicker = ActionCreator<{ id: InputsModelId; - from: number; - to: number; + from: string; + to: string; }>; export type NetworkComponentProps = Partial> & { diff --git a/x-pack/plugins/security_solution/public/overview/components/alerts_by_category/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/alerts_by_category/index.test.tsx index d2d9861e0ae1a7..8d004829a34f07 100644 --- a/x-pack/plugins/security_solution/public/overview/components/alerts_by_category/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/alerts_by_category/index.test.tsx @@ -26,8 +26,8 @@ jest.mock('../../../common/containers/matrix_histogram', () => { }); const theme = () => ({ eui: { ...euiDarkVars, euiSizeL: '24px' }, darkMode: true }); -const from = new Date('2020-03-31T06:00:00.000Z').valueOf(); -const to = new Date('2019-03-31T06:00:00.000Z').valueOf(); +const from = '2020-03-31T06:00:00.000Z'; +const to = '2019-03-31T06:00:00.000Z'; describe('Alerts by category', () => { let wrapper: ReactWrapper; diff --git a/x-pack/plugins/security_solution/public/overview/components/event_counts/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/event_counts/index.test.tsx index 95dd65f559470d..c4a941d845f167 100644 --- a/x-pack/plugins/security_solution/public/overview/components/event_counts/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/event_counts/index.test.tsx @@ -16,8 +16,8 @@ import { EventCounts } from '.'; jest.mock('../../../common/components/link_to'); describe('EventCounts', () => { - const from = 1579553397080; - const to = 1579639797080; + const from = '2020-01-20T20:49:57.080Z'; + const to = '2020-01-21T20:49:57.080Z'; test('it filters the `Host events` widget with a `host.name` `exists` filter', () => { const wrapper = mount( diff --git a/x-pack/plugins/security_solution/public/overview/components/host_overview/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/overview/components/host_overview/__snapshots__/index.test.tsx.snap index e5a4df59ac7e48..c9c34682519e28 100644 --- a/x-pack/plugins/security_solution/public/overview/components/host_overview/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/overview/components/host_overview/__snapshots__/index.test.tsx.snap @@ -192,11 +192,11 @@ exports[`Host Summary Component rendering it renders the default Host Summary 1` }, } } - endDate={1560837600000} + endDate="2019-06-18T06:00:00.000Z" id="hostOverview" isLoadingAnomaliesData={false} loading={false} narrowDateRange={[MockFunction]} - startDate={1560578400000} + startDate="2019-06-15T06:00:00.000Z" /> `; diff --git a/x-pack/plugins/security_solution/public/overview/components/host_overview/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/host_overview/index.test.tsx index 0286961fd78afe..71cf056f3eb626 100644 --- a/x-pack/plugins/security_solution/public/overview/components/host_overview/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/host_overview/index.test.tsx @@ -19,12 +19,12 @@ describe('Host Summary Component', () => { ); diff --git a/x-pack/plugins/security_solution/public/overview/components/host_overview/index.tsx b/x-pack/plugins/security_solution/public/overview/components/host_overview/index.tsx index 0c679cc94f787a..0a15b039b96af2 100644 --- a/x-pack/plugins/security_solution/public/overview/components/host_overview/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/host_overview/index.tsx @@ -41,8 +41,8 @@ interface HostSummaryProps { loading: boolean; isLoadingAnomaliesData: boolean; anomaliesData: Anomalies | null; - startDate: number; - endDate: number; + startDate: string; + endDate: string; narrowDateRange: NarrowDateRange; } diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_host/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_host/index.test.tsx index d019a480a8045d..5140137ce1b99b 100644 --- a/x-pack/plugins/security_solution/public/overview/components/overview_host/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/overview_host/index.test.tsx @@ -28,8 +28,8 @@ import { wait } from '../../../common/lib/helpers'; jest.mock('../../../common/lib/kibana'); jest.mock('../../../common/components/link_to'); -const startDate = 1579553397080; -const endDate = 1579639797080; +const startDate = '2020-01-20T20:49:57.080Z'; +const endDate = '2020-01-21T20:49:57.080Z'; interface MockedProvidedQuery { request: { diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_network/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_network/index.test.tsx index c7f7c4f4af2545..d2d823f6256900 100644 --- a/x-pack/plugins/security_solution/public/overview/components/overview_network/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/overview_network/index.test.tsx @@ -43,8 +43,8 @@ jest.mock('../../../common/lib/kibana', () => { }; }); -const startDate = 1579553397080; -const endDate = 1579639797080; +const startDate = '2020-01-20T20:49:57.080Z'; +const endDate = '2020-01-21T20:49:57.080Z'; interface MockedProvidedQuery { request: { diff --git a/x-pack/plugins/security_solution/public/overview/components/signals_by_category/index.tsx b/x-pack/plugins/security_solution/public/overview/components/signals_by_category/index.tsx index 2fddb996ccef3b..fbfdefa13d7385 100644 --- a/x-pack/plugins/security_solution/public/overview/components/signals_by_category/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/signals_by_category/index.tsx @@ -52,7 +52,11 @@ const SignalsByCategoryComponent: React.FC = ({ return; } const [min, max] = x; - setAbsoluteRangeDatePicker({ id: setAbsoluteRangeDatePickerTarget, from: min, to: max }); + setAbsoluteRangeDatePicker({ + id: setAbsoluteRangeDatePickerTarget, + from: new Date(min).toISOString(), + to: new Date(max).toISOString(), + }); }, // eslint-disable-next-line react-hooks/exhaustive-deps [setAbsoluteRangeDatePicker] diff --git a/x-pack/plugins/security_solution/public/overview/containers/overview_host/index.tsx b/x-pack/plugins/security_solution/public/overview/containers/overview_host/index.tsx index 89761e104d70f2..76ea1f3b4af756 100644 --- a/x-pack/plugins/security_solution/public/overview/containers/overview_host/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/containers/overview_host/index.tsx @@ -32,8 +32,8 @@ export interface OverviewHostArgs { export interface OverviewHostProps extends QueryTemplateProps { children: (args: OverviewHostArgs) => React.ReactNode; sourceId: string; - endDate: number; - startDate: number; + endDate: string; + startDate: string; } const OverviewHostComponentQuery = React.memo( diff --git a/x-pack/plugins/security_solution/public/overview/containers/overview_network/index.tsx b/x-pack/plugins/security_solution/public/overview/containers/overview_network/index.tsx index 86242adf3f47fa..38c035f6883b69 100644 --- a/x-pack/plugins/security_solution/public/overview/containers/overview_network/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/containers/overview_network/index.tsx @@ -32,8 +32,8 @@ export interface OverviewNetworkArgs { export interface OverviewNetworkProps extends QueryTemplateProps { children: (args: OverviewNetworkArgs) => React.ReactNode; sourceId: string; - endDate: number; - startDate: number; + endDate: string; + startDate: string; } export const OverviewNetworkComponentQuery = React.memo( diff --git a/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx b/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx index 4262afd67ba036..f7c77bc2dfdf88 100644 --- a/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx @@ -22,9 +22,12 @@ import { useIngestEnabledCheck } from '../../common/hooks/endpoint/ingest_enable jest.mock('../../common/lib/kibana'); jest.mock('../../common/containers/source'); jest.mock('../../common/containers/use_global_time', () => ({ - useGlobalTime: jest - .fn() - .mockReturnValue({ from: 0, isInitializing: false, to: 0, setQuery: jest.fn() }), + useGlobalTime: jest.fn().mockReturnValue({ + from: '2020-07-07T08:20:18.966Z', + isInitializing: false, + to: '2020-07-08T08:20:18.966Z', + setQuery: jest.fn(), + }), })); // Test will fail because we will to need to mock some core services to make the test work diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/export_timeline/mocks.ts b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/export_timeline/mocks.ts index 34d763839003c6..89a6dbd496bc38 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/export_timeline/mocks.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/export_timeline/mocks.ts @@ -79,7 +79,7 @@ export const mockSelectedTimeline = [ }, }, title: 'duplicate timeline', - dateRange: { start: 1582538951145, end: 1582625351145 }, + dateRange: { start: '2020-02-24T10:09:11.145Z', end: '2020-02-25T10:09:11.145Z' }, savedQueryId: null, sort: { columnId: '@timestamp', sortDirection: 'desc' }, created: 1583866966262, diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.test.ts b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.test.ts index 89a35fb838a964..5759d96b95f9e5 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.test.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.test.ts @@ -39,6 +39,7 @@ import sinon from 'sinon'; import { TimelineType, TimelineStatus } from '../../../../common/types/timeline'; jest.mock('../../../common/store/inputs/actions'); +jest.mock('../../../common/components/url_state/normalize_time_range.ts'); jest.mock('../../store/timeline/actions'); jest.mock('../../../common/store/app/actions'); jest.mock('uuid', () => { @@ -262,10 +263,7 @@ describe('helpers', () => { }, ], dataProviders: [], - dateRange: { - end: 0, - start: 0, - }, + dateRange: { start: '2020-07-07T08:20:18.966Z', end: '2020-07-08T08:20:18.966Z' }, description: '', deletedEventIds: [], eventIdToNoteIds: {}, @@ -360,10 +358,7 @@ describe('helpers', () => { }, ], dataProviders: [], - dateRange: { - end: 0, - start: 0, - }, + dateRange: { start: '2020-07-07T08:20:18.966Z', end: '2020-07-08T08:20:18.966Z' }, description: '', deletedEventIds: [], eventIdToNoteIds: {}, @@ -498,6 +493,7 @@ describe('helpers', () => { ], version: '1', dataProviders: [], + dateRange: { start: '2020-07-07T08:20:18.966Z', end: '2020-07-08T08:20:18.966Z' }, description: '', deletedEventIds: [], eventIdToNoteIds: {}, @@ -526,10 +522,6 @@ describe('helpers', () => { noteIds: [], pinnedEventIds: {}, pinnedEventsSaveObject: {}, - dateRange: { - start: 0, - end: 0, - }, selectedEventIds: {}, show: false, showCheckboxes: false, @@ -623,6 +615,7 @@ describe('helpers', () => { }, ], version: '1', + dateRange: { start: '2020-07-07T08:20:18.966Z', end: '2020-07-08T08:20:18.966Z' }, dataProviders: [], description: '', deletedEventIds: [], @@ -695,10 +688,6 @@ describe('helpers', () => { noteIds: [], pinnedEventIds: {}, pinnedEventsSaveObject: {}, - dateRange: { - start: 0, - end: 0, - }, selectedEventIds: {}, show: false, showCheckboxes: false, @@ -757,15 +746,15 @@ describe('helpers', () => { timelineDispatch({ duplicate: true, id: 'timeline-1', - from: 1585233356356, - to: 1585233716356, + from: '2020-03-26T14:35:56.356Z', + to: '2020-03-26T14:41:56.356Z', notes: [], timeline: mockTimelineModel, })(); expect(dispatchSetTimelineRangeDatePicker).toHaveBeenCalledWith({ - from: 1585233356356, - to: 1585233716356, + from: '2020-03-26T14:35:56.356Z', + to: '2020-03-26T14:41:56.356Z', }); }); @@ -773,8 +762,8 @@ describe('helpers', () => { timelineDispatch({ duplicate: true, id: 'timeline-1', - from: 1585233356356, - to: 1585233716356, + from: '2020-03-26T14:35:56.356Z', + to: '2020-03-26T14:41:56.356Z', notes: [], timeline: mockTimelineModel, })(); @@ -789,8 +778,8 @@ describe('helpers', () => { timelineDispatch({ duplicate: true, id: 'timeline-1', - from: 1585233356356, - to: 1585233716356, + from: '2020-03-26T14:35:56.356Z', + to: '2020-03-26T14:41:56.356Z', notes: [], timeline: mockTimelineModel, })(); @@ -803,8 +792,8 @@ describe('helpers', () => { timelineDispatch({ duplicate: true, id: 'timeline-1', - from: 1585233356356, - to: 1585233716356, + from: '2020-03-26T14:35:56.356Z', + to: '2020-03-26T14:41:56.356Z', notes: [], timeline: mockTimelineModel, })(); @@ -826,8 +815,8 @@ describe('helpers', () => { timelineDispatch({ duplicate: true, id: 'timeline-1', - from: 1585233356356, - to: 1585233716356, + from: '2020-03-26T14:35:56.356Z', + to: '2020-03-26T14:41:56.356Z', notes: [], timeline: mockTimeline, })(); @@ -850,8 +839,8 @@ describe('helpers', () => { timelineDispatch({ duplicate: true, id: 'timeline-1', - from: 1585233356356, - to: 1585233716356, + from: '2020-03-26T14:35:56.356Z', + to: '2020-03-26T14:41:56.356Z', notes: [], timeline: mockTimeline, })(); @@ -879,8 +868,8 @@ describe('helpers', () => { timelineDispatch({ duplicate: false, id: 'timeline-1', - from: 1585233356356, - to: 1585233716356, + from: '2020-03-26T14:35:56.356Z', + to: '2020-03-26T14:41:56.356Z', notes: [ { created: 1585233356356, @@ -913,8 +902,8 @@ describe('helpers', () => { timelineDispatch({ duplicate: true, id: 'timeline-1', - from: 1585233356356, - to: 1585233716356, + from: '2020-03-26T14:35:56.356Z', + to: '2020-03-26T14:41:56.356Z', notes: [], timeline: mockTimelineModel, ruleNote: '# this would be some markdown', diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.ts b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.ts index 03a6d475b3426e..04aef6f07c60af 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/helpers.ts @@ -49,9 +49,9 @@ import { } from '../timeline/body/constants'; import { OpenTimelineResult, UpdateTimeline, DispatchUpdateTimeline } from './types'; -import { getTimeRangeSettings } from '../../../common/utils/default_date_settings'; import { createNote } from '../notes/helpers'; import { IS_OPERATOR } from '../timeline/data_providers/data_provider'; +import { normalizeTimeRange } from '../../../common/components/url_state/normalize_time_range'; export const OPEN_TIMELINE_CLASS_NAME = 'open-timeline'; @@ -313,10 +313,13 @@ export const queryTimelineById = ({ if (onOpenTimeline != null) { onOpenTimeline(timeline); } else if (updateTimeline) { - const { from, to } = getTimeRangeSettings(); + const { from, to } = normalizeTimeRange({ + from: getOr(null, 'dateRange.start', timeline), + to: getOr(null, 'dateRange.end', timeline), + }); updateTimeline({ duplicate, - from: getOr(from, 'dateRange.start', timeline), + from, id: 'timeline-1', notes, timeline: { @@ -324,7 +327,7 @@ export const queryTimelineById = ({ graphEventId, show: openTimeline, }, - to: getOr(to, 'dateRange.end', timeline), + to, })(); } }) diff --git a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/types.ts b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/types.ts index a8485328e83933..eb5a03baad88c2 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/open_timeline/types.ts +++ b/x-pack/plugins/security_solution/public/timelines/components/open_timeline/types.ts @@ -189,10 +189,10 @@ export interface OpenTimelineProps { export interface UpdateTimeline { duplicate: boolean; id: string; - from: number; + from: string; notes: NoteResult[] | null | undefined; timeline: TimelineModel; - to: number; + to: string; ruleNote?: string; } diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/__snapshots__/timeline.test.tsx.snap b/x-pack/plugins/security_solution/public/timelines/components/timeline/__snapshots__/timeline.test.tsx.snap index 3508e12cb1be15..d76ddace40a5a4 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/__snapshots__/timeline.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/__snapshots__/timeline.test.tsx.snap @@ -804,7 +804,8 @@ In other use cases the message field can be used to concatenate different values }, ] } - end={1521862432253} + docValueFields={Array []} + end="2018-03-24T03:33:52.253Z" eventType="raw" filters={Array []} id="foo" @@ -901,6 +902,7 @@ In other use cases the message field can be used to concatenate different values } indexToAdd={Array []} isLive={false} + isLoadingSource={false} isSaving={false} itemsPerPage={5} itemsPerPageOptions={ @@ -928,7 +930,7 @@ In other use cases the message field can be used to concatenate different values "sortDirection": "desc", } } - start={1521830963132} + start="2018-03-23T18:49:23.132Z" status="active" timelineType="default" toggleColumn={[MockFunction]} diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/index.tsx index fc892f5b8e6b13..9f0c4747db0572 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/index.tsx @@ -6,7 +6,7 @@ import React from 'react'; -import { BrowserFields } from '../../../../../common/containers/source'; +import { BrowserFields, DocValueFields } from '../../../../../common/containers/source'; import { TimelineItem, TimelineNonEcsData } from '../../../../../graphql/types'; import { ColumnHeaderOptions } from '../../../../../timelines/store/timeline/model'; import { maxDelay } from '../../../../../common/lib/helpers/scheduler'; @@ -33,6 +33,7 @@ interface Props { columnRenderers: ColumnRenderer[]; containerElementRef: HTMLDivElement; data: TimelineItem[]; + docValueFields: DocValueFields[]; eventIdToNoteIds: Readonly>; getNotesByIds: (noteIds: string[]) => Note[]; id: string; @@ -59,6 +60,7 @@ const EventsComponent: React.FC = ({ columnRenderers, containerElementRef, data, + docValueFields, eventIdToNoteIds, getNotesByIds, id, @@ -85,6 +87,7 @@ const EventsComponent: React.FC = ({ browserFields={browserFields} columnHeaders={columnHeaders} columnRenderers={columnRenderers} + docValueFields={docValueFields} event={event} eventIdToNoteIds={eventIdToNoteIds} getNotesByIds={getNotesByIds} diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx index d2175c728aa2a4..f93a152211a66e 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/events/stateful_event.tsx @@ -9,7 +9,7 @@ import { useSelector } from 'react-redux'; import uuid from 'uuid'; import VisibilitySensor from 'react-visibility-sensor'; -import { BrowserFields } from '../../../../../common/containers/source'; +import { BrowserFields, DocValueFields } from '../../../../../common/containers/source'; import { TimelineDetailsQuery } from '../../../../containers/details'; import { TimelineItem, DetailItem, TimelineNonEcsData } from '../../../../../graphql/types'; import { requestIdleCallbackViaScheduler } from '../../../../../common/lib/helpers/scheduler'; @@ -43,6 +43,7 @@ interface Props { browserFields: BrowserFields; columnHeaders: ColumnHeaderOptions[]; columnRenderers: ColumnRenderer[]; + docValueFields: DocValueFields[]; event: TimelineItem; eventIdToNoteIds: Readonly>; getNotesByIds: (noteIds: string[]) => Note[]; @@ -108,6 +109,7 @@ const StatefulEventComponent: React.FC = ({ containerElementRef, columnHeaders, columnRenderers, + docValueFields, event, eventIdToNoteIds, getNotesByIds, @@ -202,6 +204,7 @@ const StatefulEventComponent: React.FC = ({ if (isVisible) { return ( { columnHeaders: defaultHeaders, columnRenderers, data: mockTimelineData, + docValueFields: [], eventIdToNoteIds: {}, height: testBodyHeight, id: 'timeline-test', diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.tsx index 6bf2b5e2a391ea..86bb49fac7f3e5 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/index.tsx @@ -6,7 +6,7 @@ import React, { useMemo, useRef } from 'react'; -import { BrowserFields } from '../../../../common/containers/source'; +import { BrowserFields, DocValueFields } from '../../../../common/containers/source'; import { TimelineItem, TimelineNonEcsData } from '../../../../graphql/types'; import { Note } from '../../../../common/lib/note'; import { ColumnHeaderOptions } from '../../../../timelines/store/timeline/model'; @@ -40,6 +40,7 @@ export interface BodyProps { columnHeaders: ColumnHeaderOptions[]; columnRenderers: ColumnRenderer[]; data: TimelineItem[]; + docValueFields: DocValueFields[]; getNotesByIds: (noteIds: string[]) => Note[]; graphEventId?: string; height?: number; @@ -75,6 +76,7 @@ export const Body = React.memo( columnHeaders, columnRenderers, data, + docValueFields, eventIdToNoteIds, getNotesByIds, graphEventId, @@ -183,6 +185,7 @@ export const Body = React.memo( columnHeaders={columnHeaders} columnRenderers={columnRenderers} data={data} + docValueFields={docValueFields} eventIdToNoteIds={eventIdToNoteIds} getNotesByIds={getNotesByIds} id={id} diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/stateful_body.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/stateful_body.tsx index 141534f1dcb6f3..70971408e5003a 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/body/stateful_body.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/body/stateful_body.tsx @@ -11,7 +11,7 @@ import { connect, ConnectedProps } from 'react-redux'; import deepEqual from 'fast-deep-equal'; import { RowRendererId, TimelineId } from '../../../../../common/types/timeline'; -import { BrowserFields } from '../../../../common/containers/source'; +import { BrowserFields, DocValueFields } from '../../../../common/containers/source'; import { TimelineItem } from '../../../../graphql/types'; import { Note } from '../../../../common/lib/note'; import { appSelectors, State } from '../../../../common/store'; @@ -41,6 +41,7 @@ import { plainRowRenderer } from './renderers/plain_row_renderer'; interface OwnProps { browserFields: BrowserFields; data: TimelineItem[]; + docValueFields: DocValueFields[]; height?: number; id: string; isEventViewer?: boolean; @@ -59,6 +60,7 @@ const StatefulBodyComponent = React.memo( browserFields, columnHeaders, data, + docValueFields, eventIdToNoteIds, excludedRowRendererIds, height, @@ -192,6 +194,7 @@ const StatefulBodyComponent = React.memo( columnHeaders={columnHeaders || emptyColumnHeaders} columnRenderers={columnRenderers} data={data} + docValueFields={docValueFields} eventIdToNoteIds={eventIdToNoteIds} getNotesByIds={getNotesByIds} graphEventId={graphEventId} @@ -225,6 +228,7 @@ const StatefulBodyComponent = React.memo( deepEqual(prevProps.columnHeaders, nextProps.columnHeaders) && deepEqual(prevProps.data, nextProps.data) && deepEqual(prevProps.excludedRowRendererIds, nextProps.excludedRowRendererIds) && + deepEqual(prevProps.docValueFields, nextProps.docValueFields) && prevProps.eventIdToNoteIds === nextProps.eventIdToNoteIds && prevProps.graphEventId === nextProps.graphEventId && deepEqual(prevProps.notesById, nextProps.notesById) && diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.test.tsx index 391d367ad3dc35..c371d1862be726 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.test.tsx @@ -14,8 +14,8 @@ import { mockBrowserFields } from '../../../common/containers/source/mock'; import { EsQueryConfig, Filter, esFilters } from '../../../../../../../src/plugins/data/public'; const cleanUpKqlQuery = (str: string) => str.replace(/\n/g, '').replace(/\s\s+/g, ' '); -const startDate = new Date('2018-03-23T18:49:23.132Z').valueOf(); -const endDate = new Date('2018-03-24T03:33:52.253Z').valueOf(); +const startDate = '2018-03-23T18:49:23.132Z'; +const endDate = '2018-03-24T03:33:52.253Z'; describe('Build KQL Query', () => { test('Build KQL query with one data provider', () => { @@ -54,6 +54,14 @@ describe('Build KQL Query', () => { expect(cleanUpKqlQuery(kqlQuery)).toEqual('@timestamp: 1521848183232'); }); + test('Buld KQL query with one data provider as timestamp (numeric input as string)', () => { + const dataProviders = cloneDeep(mockDataProviders.slice(0, 1)); + dataProviders[0].queryMatch.field = '@timestamp'; + dataProviders[0].queryMatch.value = '1521848183232'; + const kqlQuery = buildGlobalQuery(dataProviders, mockBrowserFields); + expect(cleanUpKqlQuery(kqlQuery)).toEqual('@timestamp: 1521848183232'); + }); + test('Build KQL query with one data provider as date type (string input)', () => { const dataProviders = cloneDeep(mockDataProviders.slice(0, 1)); dataProviders[0].queryMatch.field = 'event.end'; @@ -70,6 +78,14 @@ describe('Build KQL Query', () => { expect(cleanUpKqlQuery(kqlQuery)).toEqual('event.end: 1521848183232'); }); + test('Buld KQL query with one data provider as date type (numeric input as string)', () => { + const dataProviders = cloneDeep(mockDataProviders.slice(0, 1)); + dataProviders[0].queryMatch.field = 'event.end'; + dataProviders[0].queryMatch.value = '1521848183232'; + const kqlQuery = buildGlobalQuery(dataProviders, mockBrowserFields); + expect(cleanUpKqlQuery(kqlQuery)).toEqual('event.end: 1521848183232'); + }); + test('Build KQL query with two data provider', () => { const dataProviders = cloneDeep(mockDataProviders.slice(0, 2)); const kqlQuery = buildGlobalQuery(dataProviders, mockBrowserFields); @@ -244,8 +260,7 @@ describe('Combined Queries', () => { isEventViewer, }) ).toEqual({ - filterQuery: - '{"bool":{"must":[],"filter":[{"bool":{"filter":[{"bool":{"should":[{"range":{"@timestamp":{"gte":1521830963132}}}],"minimum_should_match":1}},{"bool":{"should":[{"range":{"@timestamp":{"lte":1521862432253}}}],"minimum_should_match":1}}]}}],"should":[],"must_not":[]}}', + filterQuery: '{"bool":{"must":[],"filter":[{"match_all":{}}],"should":[],"must_not":[]}}', }); }); @@ -291,7 +306,7 @@ describe('Combined Queries', () => { }) ).toEqual({ filterQuery: - '{"bool":{"must":[],"filter":[{"bool":{"filter":[{"bool":{"should":[{"range":{"@timestamp":{"gte":1521830963132}}}],"minimum_should_match":1}},{"bool":{"should":[{"range":{"@timestamp":{"lte":1521862432253}}}],"minimum_should_match":1}}]}},{"exists":{"field":"host.name"}}],"should":[],"must_not":[]}}', + '{"bool":{"must":[],"filter":[{"match_all":{}},{"exists":{"field":"host.name"}}],"should":[],"must_not":[]}}', }); }); @@ -309,7 +324,7 @@ describe('Combined Queries', () => { end: endDate, })!; expect(filterQuery).toEqual( - '{"bool":{"must":[],"filter":[{"bool":{"filter":[{"bool":{"should":[{"match_phrase":{"name":"Provider 1"}}],"minimum_should_match":1}},{"bool":{"filter":[{"bool":{"should":[{"range":{"@timestamp":{"gte":1521830963132}}}],"minimum_should_match":1}},{"bool":{"should":[{"range":{"@timestamp":{"lte":1521862432253}}}],"minimum_should_match":1}}]}}]}}],"should":[],"must_not":[]}}' + '{"bool":{"must":[],"filter":[{"bool":{"should":[{"match_phrase":{"name":"Provider 1"}}],"minimum_should_match":1}}],"should":[],"must_not":[]}}' ); }); @@ -329,7 +344,7 @@ describe('Combined Queries', () => { end: endDate, })!; expect(filterQuery).toEqual( - '{"bool":{"must":[],"filter":[{"bool":{"filter":[{"bool":{"should":[{"range":{"@timestamp":{"gte":1521848183232,"lte":1521848183232}}}],"minimum_should_match":1}},{"bool":{"filter":[{"bool":{"should":[{"range":{"@timestamp":{"gte":1521830963132}}}],"minimum_should_match":1}},{"bool":{"should":[{"range":{"@timestamp":{"lte":1521862432253}}}],"minimum_should_match":1}}]}}]}}],"should":[],"must_not":[]}}' + '{"bool":{"must":[],"filter":[{"bool":{"should":[{"range":{"@timestamp":{"gte":1521848183232,"lte":1521848183232}}}],"minimum_should_match":1}}],"should":[],"must_not":[]}}' ); }); @@ -349,7 +364,7 @@ describe('Combined Queries', () => { end: endDate, })!; expect(filterQuery).toEqual( - '{"bool":{"must":[],"filter":[{"bool":{"filter":[{"bool":{"should":[{"range":{"@timestamp":{"gte":1521848183232,"lte":1521848183232}}}],"minimum_should_match":1}},{"bool":{"filter":[{"bool":{"should":[{"range":{"@timestamp":{"gte":1521830963132}}}],"minimum_should_match":1}},{"bool":{"should":[{"range":{"@timestamp":{"lte":1521862432253}}}],"minimum_should_match":1}}]}}]}}],"should":[],"must_not":[]}}' + '{"bool":{"must":[],"filter":[{"bool":{"should":[{"range":{"@timestamp":{"gte":1521848183232,"lte":1521848183232}}}],"minimum_should_match":1}}],"should":[],"must_not":[]}}' ); }); @@ -369,7 +384,7 @@ describe('Combined Queries', () => { end: endDate, })!; expect(filterQuery).toEqual( - '{"bool":{"must":[],"filter":[{"bool":{"filter":[{"bool":{"should":[{"match":{"event.end":1521848183232}}],"minimum_should_match":1}},{"bool":{"filter":[{"bool":{"should":[{"range":{"@timestamp":{"gte":1521830963132}}}],"minimum_should_match":1}},{"bool":{"should":[{"range":{"@timestamp":{"lte":1521862432253}}}],"minimum_should_match":1}}]}}]}}],"should":[],"must_not":[]}}' + '{"bool":{"must":[],"filter":[{"bool":{"should":[{"match":{"event.end":1521848183232}}],"minimum_should_match":1}}],"should":[],"must_not":[]}}' ); }); @@ -389,7 +404,7 @@ describe('Combined Queries', () => { end: endDate, })!; expect(filterQuery).toEqual( - '{"bool":{"must":[],"filter":[{"bool":{"filter":[{"bool":{"should":[{"match":{"event.end":1521848183232}}],"minimum_should_match":1}},{"bool":{"filter":[{"bool":{"should":[{"range":{"@timestamp":{"gte":1521830963132}}}],"minimum_should_match":1}},{"bool":{"should":[{"range":{"@timestamp":{"lte":1521862432253}}}],"minimum_should_match":1}}]}}]}}],"should":[],"must_not":[]}}' + '{"bool":{"must":[],"filter":[{"bool":{"should":[{"match":{"event.end":1521848183232}}],"minimum_should_match":1}}],"should":[],"must_not":[]}}' ); }); @@ -406,7 +421,7 @@ describe('Combined Queries', () => { end: endDate, })!; expect(filterQuery).toEqual( - '{"bool":{"must":[],"filter":[{"bool":{"filter":[{"bool":{"should":[{"match_phrase":{"host.name":"host-1"}}],"minimum_should_match":1}},{"bool":{"filter":[{"bool":{"should":[{"range":{"@timestamp":{"gte":1521830963132}}}],"minimum_should_match":1}},{"bool":{"should":[{"range":{"@timestamp":{"lte":1521862432253}}}],"minimum_should_match":1}}]}}]}}],"should":[],"must_not":[]}}' + '{"bool":{"must":[],"filter":[{"bool":{"should":[{"match_phrase":{"host.name":"host-1"}}],"minimum_should_match":1}}],"should":[],"must_not":[]}}' ); }); @@ -424,7 +439,7 @@ describe('Combined Queries', () => { end: endDate, })!; expect(filterQuery).toEqual( - '{"bool":{"must":[],"filter":[{"bool":{"filter":[{"bool":{"should":[{"bool":{"should":[{"match_phrase":{"name":"Provider 1"}}],"minimum_should_match":1}},{"bool":{"should":[{"match_phrase":{"host.name":"host-1"}}],"minimum_should_match":1}}],"minimum_should_match":1}},{"bool":{"filter":[{"bool":{"should":[{"range":{"@timestamp":{"gte":1521830963132}}}],"minimum_should_match":1}},{"bool":{"should":[{"range":{"@timestamp":{"lte":1521862432253}}}],"minimum_should_match":1}}]}}]}}],"should":[],"must_not":[]}}' + '{"bool":{"must":[],"filter":[{"bool":{"should":[{"bool":{"should":[{"match_phrase":{"name":"Provider 1"}}],"minimum_should_match":1}},{"bool":{"should":[{"match_phrase":{"host.name":"host-1"}}],"minimum_should_match":1}}],"minimum_should_match":1}}],"should":[],"must_not":[]}}' ); }); @@ -442,7 +457,7 @@ describe('Combined Queries', () => { end: endDate, })!; expect(filterQuery).toEqual( - '{"bool":{"must":[],"filter":[{"bool":{"filter":[{"bool":{"filter":[{"bool":{"should":[{"match_phrase":{"name":"Provider 1"}}],"minimum_should_match":1}},{"bool":{"should":[{"match_phrase":{"host.name":"host-1"}}],"minimum_should_match":1}}]}},{"bool":{"filter":[{"bool":{"should":[{"range":{"@timestamp":{"gte":1521830963132}}}],"minimum_should_match":1}},{"bool":{"should":[{"range":{"@timestamp":{"lte":1521862432253}}}],"minimum_should_match":1}}]}}]}}],"should":[],"must_not":[]}}' + '{"bool":{"must":[],"filter":[{"bool":{"filter":[{"bool":{"should":[{"match_phrase":{"name":"Provider 1"}}],"minimum_should_match":1}},{"bool":{"should":[{"match_phrase":{"host.name":"host-1"}}],"minimum_should_match":1}}]}}],"should":[],"must_not":[]}}' ); }); @@ -462,7 +477,7 @@ describe('Combined Queries', () => { end: endDate, })!; expect(filterQuery).toEqual( - '{"bool":{"must":[],"filter":[{"bool":{"filter":[{"bool":{"should":[{"bool":{"should":[{"bool":{"filter":[{"bool":{"should":[{"match_phrase":{"name":"Provider 1"}}],"minimum_should_match":1}},{"bool":{"filter":[{"bool":{"should":[{"match_phrase":{"name":"Provider 3"}}],"minimum_should_match":1}},{"bool":{"should":[{"match_phrase":{"name":"Provider 4"}}],"minimum_should_match":1}}]}}]}},{"bool":{"filter":[{"bool":{"should":[{"match_phrase":{"name":"Provider 2"}}],"minimum_should_match":1}},{"bool":{"should":[{"match_phrase":{"name":"Provider 5"}}],"minimum_should_match":1}}]}}],"minimum_should_match":1}},{"bool":{"should":[{"match_phrase":{"host.name":"host-1"}}],"minimum_should_match":1}}],"minimum_should_match":1}},{"bool":{"filter":[{"bool":{"should":[{"range":{"@timestamp":{"gte":1521830963132}}}],"minimum_should_match":1}},{"bool":{"should":[{"range":{"@timestamp":{"lte":1521862432253}}}],"minimum_should_match":1}}]}}]}}],"should":[],"must_not":[]}}' + '{"bool":{"must":[],"filter":[{"bool":{"should":[{"bool":{"should":[{"bool":{"filter":[{"bool":{"should":[{"match_phrase":{"name":"Provider 1"}}],"minimum_should_match":1}},{"bool":{"filter":[{"bool":{"should":[{"match_phrase":{"name":"Provider 3"}}],"minimum_should_match":1}},{"bool":{"should":[{"match_phrase":{"name":"Provider 4"}}],"minimum_should_match":1}}]}}]}},{"bool":{"filter":[{"bool":{"should":[{"match_phrase":{"name":"Provider 2"}}],"minimum_should_match":1}},{"bool":{"should":[{"match_phrase":{"name":"Provider 5"}}],"minimum_should_match":1}}]}}],"minimum_should_match":1}},{"bool":{"should":[{"match_phrase":{"host.name":"host-1"}}],"minimum_should_match":1}}],"minimum_should_match":1}}],"should":[],"must_not":[]}}' ); }); @@ -482,7 +497,7 @@ describe('Combined Queries', () => { end: endDate, })!; expect(filterQuery).toEqual( - '{"bool":{"must":[],"filter":[{"bool":{"filter":[{"bool":{"filter":[{"bool":{"should":[{"bool":{"filter":[{"bool":{"should":[{"match_phrase":{"name":"Provider 1"}}],"minimum_should_match":1}},{"bool":{"filter":[{"bool":{"should":[{"match_phrase":{"name":"Provider 3"}}],"minimum_should_match":1}},{"bool":{"should":[{"match_phrase":{"name":"Provider 4"}}],"minimum_should_match":1}}]}}]}},{"bool":{"filter":[{"bool":{"should":[{"match_phrase":{"name":"Provider 2"}}],"minimum_should_match":1}},{"bool":{"should":[{"match_phrase":{"name":"Provider 5"}}],"minimum_should_match":1}}]}}],"minimum_should_match":1}},{"bool":{"should":[{"match_phrase":{"host.name":"host-1"}}],"minimum_should_match":1}}]}},{"bool":{"filter":[{"bool":{"should":[{"range":{"@timestamp":{"gte":1521830963132}}}],"minimum_should_match":1}},{"bool":{"should":[{"range":{"@timestamp":{"lte":1521862432253}}}],"minimum_should_match":1}}]}}]}}],"should":[],"must_not":[]}}' + '{"bool":{"must":[],"filter":[{"bool":{"filter":[{"bool":{"should":[{"bool":{"filter":[{"bool":{"should":[{"match_phrase":{"name":"Provider 1"}}],"minimum_should_match":1}},{"bool":{"filter":[{"bool":{"should":[{"match_phrase":{"name":"Provider 3"}}],"minimum_should_match":1}},{"bool":{"should":[{"match_phrase":{"name":"Provider 4"}}],"minimum_should_match":1}}]}}]}},{"bool":{"filter":[{"bool":{"should":[{"match_phrase":{"name":"Provider 2"}}],"minimum_should_match":1}},{"bool":{"should":[{"match_phrase":{"name":"Provider 5"}}],"minimum_should_match":1}}]}}],"minimum_should_match":1}},{"bool":{"should":[{"match_phrase":{"host.name":"host-1"}}],"minimum_should_match":1}}]}}],"should":[],"must_not":[]}}' ); }); }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.tsx index a0087ab638dbf5..b21ea3e4f86e96 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { isEmpty, isNumber, get } from 'lodash/fp'; +import { isEmpty, get } from 'lodash/fp'; import memoizeOne from 'memoize-one'; import { escapeQueryValue, convertToBuildEsQuery } from '../../../common/lib/keury'; @@ -23,6 +23,8 @@ import { Filter, } from '../../../../../../../src/plugins/data/public'; +const isNumber = (value: string | number) => !isNaN(Number(value)); + const convertDateFieldToQuery = (field: string, value: string | number) => `${field}: ${isNumber(value) ? value : new Date(value).valueOf()}`; @@ -113,33 +115,28 @@ export const combineQueries = ({ filters: Filter[]; kqlQuery: Query; kqlMode: string; - start: number; - end: number; + start: string; + end: string; isEventViewer?: boolean; }): { filterQuery: string } | null => { const kuery: Query = { query: '', language: kqlQuery.language }; if (isEmpty(dataProviders) && isEmpty(kqlQuery.query) && isEmpty(filters) && !isEventViewer) { return null; } else if (isEmpty(dataProviders) && isEmpty(kqlQuery.query) && isEventViewer) { - kuery.query = `@timestamp >= ${start} and @timestamp <= ${end}`; return { filterQuery: convertToBuildEsQuery({ config, queries: [kuery], indexPattern, filters }), }; } else if (isEmpty(dataProviders) && isEmpty(kqlQuery.query) && !isEmpty(filters)) { - kuery.query = `@timestamp >= ${start} and @timestamp <= ${end}`; return { filterQuery: convertToBuildEsQuery({ config, queries: [kuery], indexPattern, filters }), }; } else if (isEmpty(dataProviders) && !isEmpty(kqlQuery.query)) { - kuery.query = `(${kqlQuery.query}) and @timestamp >= ${start} and @timestamp <= ${end}`; + kuery.query = `(${kqlQuery.query})`; return { filterQuery: convertToBuildEsQuery({ config, queries: [kuery], indexPattern, filters }), }; } else if (!isEmpty(dataProviders) && isEmpty(kqlQuery)) { - kuery.query = `(${buildGlobalQuery( - dataProviders, - browserFields - )}) and @timestamp >= ${start} and @timestamp <= ${end}`; + kuery.query = `(${buildGlobalQuery(dataProviders, browserFields)})`; return { filterQuery: convertToBuildEsQuery({ config, queries: [kuery], indexPattern, filters }), }; @@ -148,7 +145,7 @@ export const combineQueries = ({ const postpend = (q: string) => `${!isEmpty(q) ? ` ${operatorKqlQuery} (${q})` : ''}`; kuery.query = `((${buildGlobalQuery(dataProviders, browserFields)})${postpend( kqlQuery.query as string - )}) and @timestamp >= ${start} and @timestamp <= ${end}`; + )})`; return { filterQuery: convertToBuildEsQuery({ config, queries: [kuery], indexPattern, filters }), }; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/index.test.tsx index 50a7782012b76b..ce96e4e50dea07 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/index.test.tsx @@ -35,6 +35,8 @@ jest.mock('../../../common/lib/kibana', () => { }; }); +jest.mock('../../../common/components/url_state/normalize_time_range.ts'); + const mockUseResizeObserver: jest.Mock = useResizeObserver as jest.Mock; jest.mock('use-resize-observer/polyfilled'); mockUseResizeObserver.mockImplementation(() => ({})); @@ -56,8 +58,8 @@ describe('StatefulTimeline', () => { columnId: '@timestamp', sortDirection: Direction.desc, }; - const startDate = new Date('2018-03-23T18:49:23.132Z').valueOf(); - const endDate = new Date('2018-03-24T03:33:52.253Z').valueOf(); + const startDate = '2018-03-23T18:49:23.132Z'; + const endDate = '2018-03-24T03:33:52.253Z'; const mocks = [ { request: { query: timelineQuery }, result: { data: { events: mockTimelineData } } }, diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/index.tsx index c4d89fa29cb324..2d7527d8a922c5 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/index.tsx @@ -171,13 +171,17 @@ const StatefulTimelineComponent = React.memo( // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - const { indexPattern, browserFields } = useWithSource('default', indexToAdd); + const { docValueFields, indexPattern, browserFields, loading: isLoadingSource } = useWithSource( + 'default', + indexToAdd + ); return ( ( indexPattern={indexPattern} indexToAdd={indexToAdd} isLive={isLive} + isLoadingSource={isLoadingSource} isSaving={isSaving} itemsPerPage={itemsPerPage!} itemsPerPageOptions={itemsPerPageOptions!} diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.test.tsx index 546f06b60cb56a..75f684c629c701 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.test.tsx @@ -65,9 +65,9 @@ describe('Timeline QueryBar ', () => { filterManager={new FilterManager(mockUiSettingsForFilterManager)} filterQuery={{ expression: 'here: query', kind: 'kuery' }} filterQueryDraft={{ expression: 'here: query', kind: 'kuery' }} - from={0} + from={'2020-07-07T08:20:18.966Z'} fromStr={DEFAULT_FROM} - to={1} + to={'2020-07-08T08:20:18.966Z'} toStr={DEFAULT_TO} kqlMode="search" indexPattern={mockIndexPattern} @@ -107,9 +107,9 @@ describe('Timeline QueryBar ', () => { filterManager={new FilterManager(mockUiSettingsForFilterManager)} filterQuery={{ expression: 'here: query', kind: 'kuery' }} filterQueryDraft={{ expression: 'here: query', kind: 'kuery' }} - from={0} + from={'2020-07-07T08:20:18.966Z'} fromStr={DEFAULT_FROM} - to={1} + to={'2020-07-08T08:20:18.966Z'} toStr={DEFAULT_TO} kqlMode="search" indexPattern={mockIndexPattern} @@ -154,9 +154,9 @@ describe('Timeline QueryBar ', () => { filterManager={new FilterManager(mockUiSettingsForFilterManager)} filterQuery={{ expression: 'here: query', kind: 'kuery' }} filterQueryDraft={{ expression: 'here: query', kind: 'kuery' }} - from={0} + from={'2020-07-07T08:20:18.966Z'} fromStr={DEFAULT_FROM} - to={1} + to={'2020-07-08T08:20:18.966Z'} toStr={DEFAULT_TO} kqlMode="search" indexPattern={mockIndexPattern} @@ -199,9 +199,9 @@ describe('Timeline QueryBar ', () => { filterManager={new FilterManager(mockUiSettingsForFilterManager)} filterQuery={{ expression: 'here: query', kind: 'kuery' }} filterQueryDraft={{ expression: 'here: query', kind: 'kuery' }} - from={0} + from={'2020-07-07T08:20:18.966Z'} fromStr={DEFAULT_FROM} - to={1} + to={'2020-07-08T08:20:18.966Z'} toStr={DEFAULT_TO} kqlMode="search" indexPattern={mockIndexPattern} @@ -246,9 +246,9 @@ describe('Timeline QueryBar ', () => { filterManager={new FilterManager(mockUiSettingsForFilterManager)} filterQuery={{ expression: 'here: query', kind: 'kuery' }} filterQueryDraft={{ expression: 'here: query', kind: 'kuery' }} - from={0} + from={'2020-07-07T08:20:18.966Z'} fromStr={DEFAULT_FROM} - to={1} + to={'2020-07-08T08:20:18.966Z'} toStr={DEFAULT_TO} kqlMode="search" indexPattern={mockIndexPattern} @@ -291,9 +291,9 @@ describe('Timeline QueryBar ', () => { filterManager={new FilterManager(mockUiSettingsForFilterManager)} filterQuery={{ expression: 'here: query', kind: 'kuery' }} filterQueryDraft={{ expression: 'here: query', kind: 'kuery' }} - from={0} + from={'2020-07-07T08:20:18.966Z'} fromStr={DEFAULT_FROM} - to={1} + to={'2020-07-08T08:20:18.966Z'} toStr={DEFAULT_TO} kqlMode="search" indexPattern={mockIndexPattern} diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.tsx index 967c5818a87225..74f21fecd0fdab 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.tsx @@ -37,7 +37,7 @@ export interface QueryBarTimelineComponentProps { filterManager: FilterManager; filterQuery: KueryFilterQuery; filterQueryDraft: KueryFilterQuery; - from: number; + from: string; fromStr: string; kqlMode: KqlMode; indexPattern: IIndexPattern; @@ -48,7 +48,7 @@ export interface QueryBarTimelineComponentProps { setKqlFilterQueryDraft: (expression: string, kind: KueryFilterQueryKind) => void; setSavedQueryId: (savedQueryId: string | null) => void; timelineId: string; - to: number; + to: string; toStr: string; updateReduxTime: DispatchUpdateReduxTime; } diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/search_or_filter.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/search_or_filter.tsx index 4d90bd875efcc5..e04cef4ad8d934 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/search_or_filter.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/search_or_filter.tsx @@ -51,7 +51,7 @@ interface Props { filterManager: FilterManager; filterQuery: KueryFilterQuery; filterQueryDraft: KueryFilterQuery; - from: number; + from: string; fromStr: string; indexPattern: IIndexPattern; isRefreshPaused: boolean; @@ -64,7 +64,7 @@ interface Props { setSavedQueryId: (savedQueryId: string | null) => void; filters: Filter[]; savedQueryId: string | null; - to: number; + to: string; toStr: string; updateEventType: (eventType: EventType) => void; updateReduxTime: DispatchUpdateReduxTime; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/timeline.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/timeline.test.tsx index 7711cb7ba620e0..58c46af5606f47 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/timeline.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/timeline.test.tsx @@ -59,8 +59,8 @@ describe('Timeline', () => { columnId: '@timestamp', sortDirection: Direction.desc, }; - const startDate = new Date('2018-03-23T18:49:23.132Z').valueOf(); - const endDate = new Date('2018-03-24T03:33:52.253Z').valueOf(); + const startDate = '2018-03-23T18:49:23.132Z'; + const endDate = '2018-03-24T03:33:52.253Z'; const indexPattern = mockIndexPattern; @@ -76,12 +76,14 @@ describe('Timeline', () => { columns: defaultHeaders, id: 'foo', dataProviders: mockDataProviders, + docValueFields: [], end: endDate, eventType: 'raw' as TimelineComponentProps['eventType'], filters: [], indexPattern, indexToAdd: [], isLive: false, + isLoadingSource: false, isSaving: false, itemsPerPage: 5, itemsPerPageOptions: [5, 10, 20], @@ -155,6 +157,42 @@ describe('Timeline', () => { expect(wrapper.find('[data-test-subj="events-table"]').exists()).toEqual(true); }); + test('it does NOT render the timeline table when the source is loading', () => { + const wrapper = mount( + + + + + + ); + + expect(wrapper.find('[data-test-subj="events-table"]').exists()).toEqual(false); + }); + + test('it does NOT render the timeline table when start is empty', () => { + const wrapper = mount( + + + + + + ); + + expect(wrapper.find('[data-test-subj="events-table"]').exists()).toEqual(false); + }); + + test('it does NOT render the timeline table when end is empty', () => { + const wrapper = mount( + + + + + + ); + + expect(wrapper.find('[data-test-subj="events-table"]').exists()).toEqual(false); + }); + test('it does NOT render the paging footer when you do NOT have any data providers', () => { const wrapper = mount( diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/timeline.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/timeline.tsx index c1e97dcaef86ab..c27af94addeab2 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/timeline.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/timeline.tsx @@ -11,7 +11,7 @@ import { useDispatch } from 'react-redux'; import styled from 'styled-components'; import { FlyoutHeaderWithCloseButton } from '../flyout/header_with_close_button'; -import { BrowserFields } from '../../../common/containers/source'; +import { BrowserFields, DocValueFields } from '../../../common/containers/source'; import { TimelineQuery } from '../../containers/index'; import { Direction } from '../../../graphql/types'; import { useKibana } from '../../../common/lib/kibana'; @@ -98,7 +98,8 @@ export interface Props { browserFields: BrowserFields; columns: ColumnHeaderOptions[]; dataProviders: DataProvider[]; - end: number; + docValueFields: DocValueFields[]; + end: string; eventType?: EventType; filters: Filter[]; graphEventId?: string; @@ -106,6 +107,7 @@ export interface Props { indexPattern: IIndexPattern; indexToAdd: string[]; isLive: boolean; + isLoadingSource: boolean; isSaving: boolean; itemsPerPage: number; itemsPerPageOptions: number[]; @@ -121,7 +123,7 @@ export interface Props { onToggleDataProviderType: OnToggleDataProviderType; show: boolean; showCallOutUnauthorizedMsg: boolean; - start: number; + start: string; sort: Sort; status: TimelineStatusLiteral; toggleColumn: (column: ColumnHeaderOptions) => void; @@ -134,6 +136,7 @@ export const TimelineComponent: React.FC = ({ browserFields, columns, dataProviders, + docValueFields, end, eventType, filters, @@ -142,6 +145,7 @@ export const TimelineComponent: React.FC = ({ indexPattern, indexToAdd, isLive, + isLoadingSource, isSaving, itemsPerPage, itemsPerPageOptions, @@ -167,17 +171,47 @@ export const TimelineComponent: React.FC = ({ const dispatch = useDispatch(); const kibana = useKibana(); const [filterManager] = useState(new FilterManager(kibana.services.uiSettings)); - const combinedQueries = combineQueries({ - config: esQuery.getEsQueryConfig(kibana.services.uiSettings), - dataProviders, - indexPattern, - browserFields, - filters, - kqlQuery: { query: kqlQueryExpression, language: 'kuery' }, - kqlMode, - start, - end, - }); + const esQueryConfig = useMemo(() => esQuery.getEsQueryConfig(kibana.services.uiSettings), [ + kibana.services.uiSettings, + ]); + const kqlQuery = useMemo(() => ({ query: kqlQueryExpression, language: 'kuery' }), [ + kqlQueryExpression, + ]); + const combinedQueries = useMemo( + () => + combineQueries({ + config: esQueryConfig, + dataProviders, + indexPattern, + browserFields, + filters, + kqlQuery, + kqlMode, + start, + end, + }), + [ + browserFields, + dataProviders, + esQueryConfig, + start, + end, + filters, + indexPattern, + kqlMode, + kqlQuery, + ] + ); + + const canQueryTimeline = useMemo( + () => + combinedQueries != null && + isLoadingSource != null && + !isLoadingSource && + !isEmpty(start) && + !isEmpty(end), + [isLoadingSource, combinedQueries, start, end] + ); const columnsHeader = isEmpty(columns) ? defaultHeaders : columns; const timelineQueryFields = useMemo(() => columnsHeader.map((c) => c.id), [columnsHeader]); const timelineQuerySortField = useMemo( @@ -239,16 +273,19 @@ export const TimelineComponent: React.FC = ({ - {combinedQueries != null ? ( + {canQueryTimeline ? ( {({ events, @@ -277,6 +314,7 @@ export const TimelineComponent: React.FC = ({ React.ReactElement; + docValueFields: DocValueFields[]; indexName: string; eventId: string; executeQuery: boolean; @@ -34,12 +36,14 @@ const getDetailsEvent = memoizeOne( const TimelineDetailsQueryComponent: React.FC = ({ children, + docValueFields, indexName, eventId, executeQuery, sourceId, }) => { const variables: GetTimelineDetailsQuery.Variables = { + docValueFields, sourceId, indexName, eventId, diff --git a/x-pack/plugins/security_solution/public/timelines/containers/index.gql_query.ts b/x-pack/plugins/security_solution/public/timelines/containers/index.gql_query.ts index 6c90b39a8e688c..5a162fd2206a1b 100644 --- a/x-pack/plugins/security_solution/public/timelines/containers/index.gql_query.ts +++ b/x-pack/plugins/security_solution/public/timelines/containers/index.gql_query.ts @@ -15,6 +15,8 @@ export const timelineQuery = gql` $filterQuery: String $defaultIndex: [String!]! $inspect: Boolean! + $docValueFields: [docValueFieldsInput!]! + $timerange: TimerangeInput! ) { source(id: $sourceId) { id @@ -24,6 +26,8 @@ export const timelineQuery = gql` sortField: $sortField filterQuery: $filterQuery defaultIndex: $defaultIndex + docValueFields: $docValueFields + timerange: $timerange ) { totalCount inspect @include(if: $inspect) { diff --git a/x-pack/plugins/security_solution/public/timelines/containers/index.tsx b/x-pack/plugins/security_solution/public/timelines/containers/index.tsx index 164d34db16d87e..510d58dbe6a696 100644 --- a/x-pack/plugins/security_solution/public/timelines/containers/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/containers/index.tsx @@ -49,6 +49,7 @@ export interface CustomReduxProps { export interface OwnProps extends QueryTemplateProps { children?: (args: TimelineArgs) => React.ReactNode; + endDate: string; eventType?: EventType; id: string; indexPattern?: IIndexPattern; @@ -56,6 +57,7 @@ export interface OwnProps extends QueryTemplateProps { limit: number; sortField: SortField; fields: string[]; + startDate: string; } type TimelineQueryProps = OwnProps & PropsFromRedux & WithKibanaProps & CustomReduxProps; @@ -77,6 +79,8 @@ class TimelineQueryComponent extends QueryTemplate< const { children, clearSignalsState, + docValueFields, + endDate, eventType = 'raw', id, indexPattern, @@ -88,6 +92,7 @@ class TimelineQueryComponent extends QueryTemplate< filterQuery, sourceId, sortField, + startDate, } = this.props; const defaultKibanaIndex = kibana.services.uiSettings.get(DEFAULT_INDEX_KEY); const defaultIndex = @@ -101,9 +106,15 @@ class TimelineQueryComponent extends QueryTemplate< fieldRequested: fields, filterQuery: createFilter(filterQuery), sourceId, + timerange: { + interval: '12h', + from: startDate, + to: endDate, + }, pagination: { limit, cursor: null, tiebreaker: null }, sortField, defaultIndex, + docValueFields: docValueFields ?? [], inspect: isInspected, }; diff --git a/x-pack/plugins/security_solution/public/timelines/store/timeline/actions.ts b/x-pack/plugins/security_solution/public/timelines/store/timeline/actions.ts index 618de48091ce8a..faeef432ea4229 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/timeline/actions.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/timeline/actions.ts @@ -56,8 +56,8 @@ export const createTimeline = actionCreator<{ id: string; dataProviders?: DataProvider[]; dateRange?: { - start: number; - end: number; + start: string; + end: string; }; excludedRowRendererIds?: RowRendererId[]; filters?: Filter[]; @@ -209,7 +209,7 @@ export const updateProviders = actionCreator<{ id: string; providers: DataProvid 'UPDATE_PROVIDERS' ); -export const updateRange = actionCreator<{ id: string; start: number; end: number }>( +export const updateRange = actionCreator<{ id: string; start: string; end: string }>( 'UPDATE_RANGE' ); diff --git a/x-pack/plugins/security_solution/public/timelines/store/timeline/defaults.ts b/x-pack/plugins/security_solution/public/timelines/store/timeline/defaults.ts index f4c4085715af9b..7980f62cff1718 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/timeline/defaults.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/timeline/defaults.ts @@ -9,11 +9,16 @@ import { TimelineType, TimelineStatus } from '../../../../common/types/timeline' import { Direction } from '../../../graphql/types'; import { DEFAULT_TIMELINE_WIDTH } from '../../components/timeline/body/constants'; import { defaultHeaders } from '../../components/timeline/body/column_headers/default_headers'; +import { normalizeTimeRange } from '../../../common/components/url_state/normalize_time_range'; import { SubsetTimelineModel, TimelineModel } from './model'; +// normalizeTimeRange uses getTimeRangeSettings which cannot be used outside Kibana context if the uiSettings is not false +const { from: start, to: end } = normalizeTimeRange({ from: '', to: '' }, false); + export const timelineDefaults: SubsetTimelineModel & Pick = { columns: defaultHeaders, dataProviders: [], + dateRange: { start, end }, deletedEventIds: [], description: '', eventType: 'all', @@ -42,10 +47,6 @@ export const timelineDefaults: SubsetTimelineModel & Pick { noteIds: [], pinnedEventIds: {}, pinnedEventsSaveObject: {}, - dateRange: { start: 1572469587644, end: 1572555987644 }, + dateRange: { start: '2019-10-30T21:06:27.644Z', end: '2019-10-31T21:06:27.644Z' }, savedObjectId: '11169110-fc22-11e9-8ca9-072f15ce2685', selectedEventIds: {}, show: true, @@ -158,9 +158,9 @@ describe('Epic Timeline', () => { expect( convertTimelineAsInput(timelineModel, { kind: 'absolute', - from: 1572469587644, + from: '2019-10-30T21:06:27.644Z', fromStr: undefined, - to: 1572555987644, + to: '2019-10-31T21:06:27.644Z', toStr: undefined, }) ).toEqual({ @@ -228,8 +228,8 @@ describe('Epic Timeline', () => { }, ], dateRange: { - end: 1572555987644, - start: 1572469587644, + end: '2019-10-31T21:06:27.644Z', + start: '2019-10-30T21:06:27.644Z', }, description: '', eventType: 'all', diff --git a/x-pack/plugins/security_solution/public/timelines/store/timeline/epic_local_storage.test.tsx b/x-pack/plugins/security_solution/public/timelines/store/timeline/epic_local_storage.test.tsx index 7d65181db65fd8..bd1fac9b054742 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/timeline/epic_local_storage.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/store/timeline/epic_local_storage.test.tsx @@ -65,8 +65,8 @@ describe('epicLocalStorage', () => { columnId: '@timestamp', sortDirection: Direction.desc, }; - const startDate = new Date('2018-03-23T18:49:23.132Z').valueOf(); - const endDate = new Date('2018-03-24T03:33:52.253Z').valueOf(); + const startDate = '2018-03-23T18:49:23.132Z'; + const endDate = '2018-03-24T03:33:52.253Z'; const indexPattern = mockIndexPattern; @@ -83,12 +83,14 @@ describe('epicLocalStorage', () => { columns: defaultHeaders, id: 'foo', dataProviders: mockDataProviders, + docValueFields: [], end: endDate, eventType: 'raw' as TimelineComponentProps['eventType'], filters: [], indexPattern, indexToAdd: [], isLive: false, + isLoadingSource: false, isSaving: false, itemsPerPage: 5, itemsPerPageOptions: [5, 10, 20], diff --git a/x-pack/plugins/security_solution/public/timelines/store/timeline/helpers.ts b/x-pack/plugins/security_solution/public/timelines/store/timeline/helpers.ts index 59f47297b1f65f..2d16892329e198 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/timeline/helpers.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/timeline/helpers.ts @@ -26,6 +26,7 @@ import { TimelineType, RowRendererId, } from '../../../../common/types/timeline'; +import { normalizeTimeRange } from '../../../common/components/url_state/normalize_time_range'; import { timelineDefaults } from './defaults'; import { ColumnHeaderOptions, KqlMode, TimelineModel, EventType } from './model'; @@ -131,8 +132,8 @@ interface AddNewTimelineParams { columns: ColumnHeaderOptions[]; dataProviders?: DataProvider[]; dateRange?: { - start: number; - end: number; + start: string; + end: string; }; excludedRowRendererIds?: RowRendererId[]; filters?: Filter[]; @@ -153,7 +154,7 @@ interface AddNewTimelineParams { export const addNewTimeline = ({ columns, dataProviders = [], - dateRange = { start: 0, end: 0 }, + dateRange: mayDateRange, excludedRowRendererIds = [], filters = timelineDefaults.filters, id, @@ -165,6 +166,8 @@ export const addNewTimeline = ({ timelineById, timelineType, }: AddNewTimelineParams): TimelineById => { + const { from: startDateRange, to: endDateRange } = normalizeTimeRange({ from: '', to: '' }); + const dateRange = mayDateRange ?? { start: startDateRange, end: endDateRange }; const templateTimelineInfo = timelineType === TimelineType.template ? { @@ -752,8 +755,8 @@ export const updateTimelineProviders = ({ interface UpdateTimelineRangeParams { id: string; - start: number; - end: number; + start: string; + end: string; timelineById: TimelineById; } diff --git a/x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts b/x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts index 95d525c7eb59f4..9a8399d3669678 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/timeline/model.ts @@ -101,8 +101,8 @@ export interface TimelineModel { pinnedEventsSaveObject: Record; /** Specifies the granularity of the date range (e.g. 1 Day / Week / Month) applicable to the mini-map */ dateRange: { - start: number; - end: number; + start: string; + end: string; }; savedQueryId?: string | null; /** Events selected on this timeline -- eventId to TimelineNonEcsData[] mapping of data required for batch actions **/ diff --git a/x-pack/plugins/security_solution/public/timelines/store/timeline/reducer.test.ts b/x-pack/plugins/security_solution/public/timelines/store/timeline/reducer.test.ts index 4cfc20eb817059..0197ccc7eec05a 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/timeline/reducer.test.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/timeline/reducer.test.ts @@ -48,6 +48,8 @@ import { ColumnHeaderOptions } from './model'; import { timelineDefaults } from './defaults'; import { TimelineById } from './types'; +jest.mock('../../../common/components/url_state/normalize_time_range.ts'); + const timelineByIdMock: TimelineById = { foo: { dataProviders: [ @@ -92,8 +94,8 @@ const timelineByIdMock: TimelineById = { pinnedEventIds: {}, pinnedEventsSaveObject: {}, dateRange: { - start: 0, - end: 0, + start: '2020-07-07T08:20:18.966Z', + end: '2020-07-08T08:20:18.966Z', }, selectedEventIds: {}, show: true, @@ -1009,8 +1011,8 @@ describe('Timeline', () => { test('should return a new reference and not the same reference', () => { const update = updateTimelineRange({ id: 'foo', - start: 23, - end: 33, + start: '2020-07-07T08:20:18.966Z', + end: '2020-07-08T08:20:18.966Z', timelineById: timelineByIdMock, }); expect(update).not.toBe(timelineByIdMock); @@ -1019,16 +1021,16 @@ describe('Timeline', () => { test('should update the timeline range', () => { const update = updateTimelineRange({ id: 'foo', - start: 23, - end: 33, + start: '2020-07-07T08:20:18.966Z', + end: '2020-07-08T08:20:18.966Z', timelineById: timelineByIdMock, }); expect(update).toEqual( set( 'foo.dateRange', { - start: 23, - end: 33, + start: '2020-07-07T08:20:18.966Z', + end: '2020-07-08T08:20:18.966Z', }, timelineByIdMock ) @@ -1135,8 +1137,8 @@ describe('Timeline', () => { templateTimelineId: null, noteIds: [], dateRange: { - start: 0, - end: 0, + start: '2020-07-07T08:20:18.966Z', + end: '2020-07-08T08:20:18.966Z', }, selectedEventIds: {}, show: true, @@ -1231,8 +1233,8 @@ describe('Timeline', () => { templateTimelineId: null, noteIds: [], dateRange: { - start: 0, - end: 0, + start: '2020-07-07T08:20:18.966Z', + end: '2020-07-08T08:20:18.966Z', }, selectedEventIds: {}, show: true, @@ -1437,8 +1439,8 @@ describe('Timeline', () => { templateTimelineId: null, noteIds: [], dateRange: { - start: 0, - end: 0, + start: '2020-07-07T08:20:18.966Z', + end: '2020-07-08T08:20:18.966Z', }, selectedEventIds: {}, show: true, @@ -1533,8 +1535,8 @@ describe('Timeline', () => { templateTimelineVersion: null, noteIds: [], dateRange: { - start: 0, - end: 0, + start: '2020-07-07T08:20:18.966Z', + end: '2020-07-08T08:20:18.966Z', }, selectedEventIds: {}, show: true, @@ -1635,8 +1637,8 @@ describe('Timeline', () => { templateTimelineId: null, noteIds: [], dateRange: { - start: 0, - end: 0, + start: '2020-07-07T08:20:18.966Z', + end: '2020-07-08T08:20:18.966Z', }, selectedEventIds: {}, show: true, @@ -1738,8 +1740,8 @@ describe('Timeline', () => { templateTimelineVersion: null, noteIds: [], dateRange: { - start: 0, - end: 0, + start: '2020-07-07T08:20:18.966Z', + end: '2020-07-08T08:20:18.966Z', }, selectedEventIds: {}, show: true, @@ -1933,8 +1935,8 @@ describe('Timeline', () => { templateTimelineId: null, noteIds: [], dateRange: { - start: 0, - end: 0, + start: '2020-07-07T08:20:18.966Z', + end: '2020-07-08T08:20:18.966Z', }, selectedEventIds: {}, show: true, @@ -2013,8 +2015,8 @@ describe('Timeline', () => { templateTimelineId: null, noteIds: [], dateRange: { - start: 0, - end: 0, + start: '2020-07-07T08:20:18.966Z', + end: '2020-07-08T08:20:18.966Z', }, selectedEventIds: {}, show: true, @@ -2117,8 +2119,8 @@ describe('Timeline', () => { templateTimelineId: null, noteIds: [], dateRange: { - start: 0, - end: 0, + start: '2020-07-07T08:20:18.966Z', + end: '2020-07-08T08:20:18.966Z', }, selectedEventIds: {}, show: true, diff --git a/x-pack/plugins/security_solution/server/graphql/authentications/schema.gql.ts b/x-pack/plugins/security_solution/server/graphql/authentications/schema.gql.ts index 20935ce9ed03fc..648a65fa246827 100644 --- a/x-pack/plugins/security_solution/server/graphql/authentications/schema.gql.ts +++ b/x-pack/plugins/security_solution/server/graphql/authentications/schema.gql.ts @@ -41,6 +41,7 @@ export const authenticationsSchema = gql` pagination: PaginationInputPaginated! filterQuery: String defaultIndex: [String!]! + docValueFields: [docValueFieldsInput!]! ): AuthenticationsData! } `; diff --git a/x-pack/plugins/security_solution/server/graphql/events/resolvers.ts b/x-pack/plugins/security_solution/server/graphql/events/resolvers.ts index a9ef6bc682c845..ef28ac523ff85e 100644 --- a/x-pack/plugins/security_solution/server/graphql/events/resolvers.ts +++ b/x-pack/plugins/security_solution/server/graphql/events/resolvers.ts @@ -58,6 +58,7 @@ export const createEventsResolvers = ( async LastEventTime(source, args, { req }) { const options: LastEventTimeRequestOptions = { defaultIndex: args.defaultIndex, + docValueFields: args.docValueFields, sourceConfiguration: source.configuration, indexKey: args.indexKey, details: args.details, diff --git a/x-pack/plugins/security_solution/server/graphql/events/schema.gql.ts b/x-pack/plugins/security_solution/server/graphql/events/schema.gql.ts index 3b71977bc0d478..eee4bc3e3a33fd 100644 --- a/x-pack/plugins/security_solution/server/graphql/events/schema.gql.ts +++ b/x-pack/plugins/security_solution/server/graphql/events/schema.gql.ts @@ -76,17 +76,20 @@ export const eventsSchema = gql` timerange: TimerangeInput filterQuery: String defaultIndex: [String!]! + docValueFields: [docValueFieldsInput!]! ): TimelineData! TimelineDetails( eventId: String! indexName: String! defaultIndex: [String!]! + docValueFields: [docValueFieldsInput!]! ): TimelineDetailsData! LastEventTime( id: String indexKey: LastEventIndexKey! details: LastTimeDetails! defaultIndex: [String!]! + docValueFields: [docValueFieldsInput!]! ): LastEventTimeData! } `; diff --git a/x-pack/plugins/security_solution/server/graphql/hosts/resolvers.ts b/x-pack/plugins/security_solution/server/graphql/hosts/resolvers.ts index e37ade585e8bed..181ee3c2b4e949 100644 --- a/x-pack/plugins/security_solution/server/graphql/hosts/resolvers.ts +++ b/x-pack/plugins/security_solution/server/graphql/hosts/resolvers.ts @@ -71,6 +71,7 @@ export const createHostsResolvers = ( sourceConfiguration: source.configuration, hostName: args.hostName, defaultIndex: args.defaultIndex, + docValueFields: args.docValueFields, }; return libs.hosts.getHostFirstLastSeen(req, options); }, diff --git a/x-pack/plugins/security_solution/server/graphql/hosts/schema.gql.ts b/x-pack/plugins/security_solution/server/graphql/hosts/schema.gql.ts index 02f8341cd6fd9b..48bb0cbe37afdd 100644 --- a/x-pack/plugins/security_solution/server/graphql/hosts/schema.gql.ts +++ b/x-pack/plugins/security_solution/server/graphql/hosts/schema.gql.ts @@ -99,6 +99,7 @@ export const hostsSchema = gql` sort: HostsSortField! filterQuery: String defaultIndex: [String!]! + docValueFields: [docValueFieldsInput!]! ): HostsData! HostOverview( id: String @@ -106,6 +107,11 @@ export const hostsSchema = gql` timerange: TimerangeInput! defaultIndex: [String!]! ): HostItem! - HostFirstLastSeen(id: String, hostName: String!, defaultIndex: [String!]!): FirstLastSeenHost! + HostFirstLastSeen( + id: String + hostName: String! + defaultIndex: [String!]! + docValueFields: [docValueFieldsInput!]! + ): FirstLastSeenHost! } `; diff --git a/x-pack/plugins/security_solution/server/graphql/ip_details/schema.gql.ts b/x-pack/plugins/security_solution/server/graphql/ip_details/schema.gql.ts index 4684449c1b80ff..2531f8d169327b 100644 --- a/x-pack/plugins/security_solution/server/graphql/ip_details/schema.gql.ts +++ b/x-pack/plugins/security_solution/server/graphql/ip_details/schema.gql.ts @@ -38,6 +38,7 @@ const ipOverviewSchema = gql` filterQuery: String ip: String! defaultIndex: [String!]! + docValueFields: [docValueFieldsInput!]! ): IpOverviewData } `; diff --git a/x-pack/plugins/security_solution/server/graphql/network/schema.gql.ts b/x-pack/plugins/security_solution/server/graphql/network/schema.gql.ts index 15e2d832a73c9d..9bb8a48c12f0d9 100644 --- a/x-pack/plugins/security_solution/server/graphql/network/schema.gql.ts +++ b/x-pack/plugins/security_solution/server/graphql/network/schema.gql.ts @@ -238,6 +238,7 @@ export const networkSchema = gql` defaultIndex: [String!]! timerange: TimerangeInput! stackByField: String + docValueFields: [docValueFieldsInput!]! ): NetworkDsOverTimeData! NetworkHttp( id: String diff --git a/x-pack/plugins/security_solution/server/graphql/timeline/schema.gql.ts b/x-pack/plugins/security_solution/server/graphql/timeline/schema.gql.ts index 7cbeea67b27509..fce81e2f0dce09 100644 --- a/x-pack/plugins/security_solution/server/graphql/timeline/schema.gql.ts +++ b/x-pack/plugins/security_solution/server/graphql/timeline/schema.gql.ts @@ -34,8 +34,8 @@ const kueryFilterQuery = ` `; const dateRange = ` - start: Float - end: Float + start: ToAny + end: ToAny `; const favoriteTimeline = ` diff --git a/x-pack/plugins/security_solution/server/graphql/types.ts b/x-pack/plugins/security_solution/server/graphql/types.ts index 1eaf47ad43812a..f8a614e86f28e9 100644 --- a/x-pack/plugins/security_solution/server/graphql/types.ts +++ b/x-pack/plugins/security_solution/server/graphql/types.ts @@ -26,9 +26,9 @@ export interface TimerangeInput { /** The interval string to use for last bucket. The format is '{value}{unit}'. For example '5m' would return the metrics for the last 5 minutes of the timespan. */ interval: string; /** The end of the timerange */ - to: number; + to: string; /** The beginning of the timerange */ - from: number; + from: string; } export interface PaginationInputPaginated { @@ -42,6 +42,12 @@ export interface PaginationInputPaginated { querySize: number; } +export interface DocValueFieldsInput { + field: string; + + format: string; +} + export interface PaginationInput { /** The limit parameter allows you to configure the maximum amount of items to be returned */ limit: number; @@ -262,9 +268,9 @@ export interface KueryFilterQueryInput { } export interface DateRangePickerInput { - start?: Maybe; + start?: Maybe; - end?: Maybe; + end?: Maybe; } export interface SortTimelineInput { @@ -2095,9 +2101,9 @@ export interface QueryMatchResult { } export interface DateRangePickerResult { - start?: Maybe; + start?: Maybe; - end?: Maybe; + end?: Maybe; } export interface FavoriteTimelineResult { @@ -2334,6 +2340,8 @@ export interface AuthenticationsSourceArgs { filterQuery?: Maybe; defaultIndex: string[]; + + docValueFields: DocValueFieldsInput[]; } export interface TimelineSourceArgs { pagination: PaginationInput; @@ -2347,6 +2355,8 @@ export interface TimelineSourceArgs { filterQuery?: Maybe; defaultIndex: string[]; + + docValueFields: DocValueFieldsInput[]; } export interface TimelineDetailsSourceArgs { eventId: string; @@ -2354,6 +2364,8 @@ export interface TimelineDetailsSourceArgs { indexName: string; defaultIndex: string[]; + + docValueFields: DocValueFieldsInput[]; } export interface LastEventTimeSourceArgs { id?: Maybe; @@ -2363,6 +2375,8 @@ export interface LastEventTimeSourceArgs { details: LastTimeDetails; defaultIndex: string[]; + + docValueFields: DocValueFieldsInput[]; } export interface HostsSourceArgs { id?: Maybe; @@ -2376,6 +2390,8 @@ export interface HostsSourceArgs { filterQuery?: Maybe; defaultIndex: string[]; + + docValueFields: DocValueFieldsInput[]; } export interface HostOverviewSourceArgs { id?: Maybe; @@ -2392,6 +2408,8 @@ export interface HostFirstLastSeenSourceArgs { hostName: string; defaultIndex: string[]; + + docValueFields: DocValueFieldsInput[]; } export interface IpOverviewSourceArgs { id?: Maybe; @@ -2401,6 +2419,8 @@ export interface IpOverviewSourceArgs { ip: string; defaultIndex: string[]; + + docValueFields: DocValueFieldsInput[]; } export interface UsersSourceArgs { filterQuery?: Maybe; @@ -2516,6 +2536,8 @@ export interface NetworkDnsHistogramSourceArgs { timerange: TimerangeInput; stackByField?: Maybe; + + docValueFields: DocValueFieldsInput[]; } export interface NetworkHttpSourceArgs { id?: Maybe; @@ -3054,6 +3076,8 @@ export namespace SourceResolvers { filterQuery?: Maybe; defaultIndex: string[]; + + docValueFields: DocValueFieldsInput[]; } export type TimelineResolver< @@ -3073,6 +3097,8 @@ export namespace SourceResolvers { filterQuery?: Maybe; defaultIndex: string[]; + + docValueFields: DocValueFieldsInput[]; } export type TimelineDetailsResolver< @@ -3086,6 +3112,8 @@ export namespace SourceResolvers { indexName: string; defaultIndex: string[]; + + docValueFields: DocValueFieldsInput[]; } export type LastEventTimeResolver< @@ -3101,6 +3129,8 @@ export namespace SourceResolvers { details: LastTimeDetails; defaultIndex: string[]; + + docValueFields: DocValueFieldsInput[]; } export type HostsResolver = Resolver< @@ -3121,6 +3151,8 @@ export namespace SourceResolvers { filterQuery?: Maybe; defaultIndex: string[]; + + docValueFields: DocValueFieldsInput[]; } export type HostOverviewResolver< @@ -3149,6 +3181,8 @@ export namespace SourceResolvers { hostName: string; defaultIndex: string[]; + + docValueFields: DocValueFieldsInput[]; } export type IpOverviewResolver< @@ -3164,6 +3198,8 @@ export namespace SourceResolvers { ip: string; defaultIndex: string[]; + + docValueFields: DocValueFieldsInput[]; } export type UsersResolver = Resolver< @@ -3334,6 +3370,8 @@ export namespace SourceResolvers { timerange: TimerangeInput; stackByField?: Maybe; + + docValueFields: DocValueFieldsInput[]; } export type NetworkHttpResolver< @@ -8559,18 +8597,18 @@ export namespace QueryMatchResultResolvers { export namespace DateRangePickerResultResolvers { export interface Resolvers { - start?: StartResolver, TypeParent, TContext>; + start?: StartResolver, TypeParent, TContext>; - end?: EndResolver, TypeParent, TContext>; + end?: EndResolver, TypeParent, TContext>; } export type StartResolver< - R = Maybe, + R = Maybe, Parent = DateRangePickerResult, TContext = SiemContext > = Resolver; export type EndResolver< - R = Maybe, + R = Maybe, Parent = DateRangePickerResult, TContext = SiemContext > = Resolver; diff --git a/x-pack/plugins/security_solution/server/lib/authentications/query.dsl.ts b/x-pack/plugins/security_solution/server/lib/authentications/query.dsl.ts index b9ed88e91f87d1..b6b72cd37efaa0 100644 --- a/x-pack/plugins/security_solution/server/lib/authentications/query.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/authentications/query.dsl.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import { isEmpty } from 'lodash/fp'; + import { createQueryFilterClauses } from '../../utils/build_query'; import { reduceFields } from '../../utils/build_query/reduce_fields'; import { hostFieldsMap, sourceFieldsMap } from '../ecs_fields'; @@ -26,6 +28,7 @@ export const buildQuery = ({ timerange: { from, to }, pagination: { querySize }, defaultIndex, + docValueFields, sourceConfiguration: { fields: { timestamp }, }, @@ -40,6 +43,7 @@ export const buildQuery = ({ [timestamp]: { gte: from, lte: to, + format: 'strict_date_optional_time', }, }, }, @@ -58,6 +62,7 @@ export const buildQuery = ({ index: defaultIndex, ignoreUnavailable: true, body: { + ...(isEmpty(docValueFields) ? { docvalue_fields: docValueFields } : {}), aggregations: { ...agg, group_by_users: { diff --git a/x-pack/plugins/security_solution/server/lib/events/elasticsearch_adapter.ts b/x-pack/plugins/security_solution/server/lib/events/elasticsearch_adapter.ts index 6ad18c5578f936..aabb18d4190988 100644 --- a/x-pack/plugins/security_solution/server/lib/events/elasticsearch_adapter.ts +++ b/x-pack/plugins/security_solution/server/lib/events/elasticsearch_adapter.ts @@ -84,7 +84,7 @@ export class ElasticsearchEventsAdapter implements EventsAdapter { request: FrameworkRequest, options: RequestDetailsOptions ): Promise { - const dsl = buildDetailsQuery(options.indexName, options.eventId); + const dsl = buildDetailsQuery(options.indexName, options.eventId, options.docValueFields ?? []); const searchResponse = await this.framework.callWithRequest( request, 'search', diff --git a/x-pack/plugins/security_solution/server/lib/events/query.dsl.ts b/x-pack/plugins/security_solution/server/lib/events/query.dsl.ts index bc95fe56294495..143ef1e9d5bf0e 100644 --- a/x-pack/plugins/security_solution/server/lib/events/query.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/events/query.dsl.ts @@ -3,74 +3,15 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ +import { isEmpty } from 'lodash/fp'; -import { SortField, TimerangeInput } from '../../graphql/types'; +import { SortField, TimerangeInput, DocValueFieldsInput } from '../../graphql/types'; import { createQueryFilterClauses } from '../../utils/build_query'; -import { RequestOptions, RequestOptionsPaginated } from '../framework'; +import { RequestOptions } from '../framework'; import { SortRequest } from '../types'; import { TimerangeFilter } from './types'; -export const buildQuery = (options: RequestOptionsPaginated) => { - const { querySize } = options.pagination; - const { fields, filterQuery } = options; - const filterClause = [...createQueryFilterClauses(filterQuery)]; - const defaultIndex = options.defaultIndex; - - const getTimerangeFilter = (timerange: TimerangeInput | undefined): TimerangeFilter[] => { - if (timerange) { - const { to, from } = timerange; - return [ - { - range: { - [options.sourceConfiguration.fields.timestamp]: { - gte: from, - lte: to, - }, - }, - }, - ]; - } - return []; - }; - - const filter = [...filterClause, ...getTimerangeFilter(options.timerange), { match_all: {} }]; - - const getSortField = (sortField: SortField) => { - if (sortField.sortFieldId) { - const field: string = - sortField.sortFieldId === 'timestamp' ? '@timestamp' : sortField.sortFieldId; - - return [ - { [field]: sortField.direction }, - { [options.sourceConfiguration.fields.tiebreaker]: sortField.direction }, - ]; - } - return []; - }; - - const sort: SortRequest = getSortField(options.sortField!); - - const dslQuery = { - allowNoIndices: true, - index: defaultIndex, - ignoreUnavailable: true, - body: { - query: { - bool: { - filter, - }, - }, - size: querySize, - track_total_hits: true, - sort, - _source: fields, - }, - }; - - return dslQuery; -}; - export const buildTimelineQuery = (options: RequestOptions) => { const { limit, cursor, tiebreaker } = options.pagination; const { fields, filterQuery } = options; @@ -86,6 +27,7 @@ export const buildTimelineQuery = (options: RequestOptions) => { [options.sourceConfiguration.fields.timestamp]: { gte: from, lte: to, + format: 'strict_date_optional_time', }, }, }, @@ -116,6 +58,7 @@ export const buildTimelineQuery = (options: RequestOptions) => { index: defaultIndex, ignoreUnavailable: true, body: { + ...(isEmpty(options.docValueFields) ? { docvalue_fields: options.docValueFields } : {}), query: { bool: { filter, @@ -141,11 +84,16 @@ export const buildTimelineQuery = (options: RequestOptions) => { return dslQuery; }; -export const buildDetailsQuery = (indexName: string, id: string) => ({ +export const buildDetailsQuery = ( + indexName: string, + id: string, + docValueFields: DocValueFieldsInput[] +) => ({ allowNoIndices: true, index: indexName, ignoreUnavailable: true, body: { + docvalue_fields: docValueFields, query: { terms: { _id: [id], diff --git a/x-pack/plugins/security_solution/server/lib/events/query.last_event_time.dsl.ts b/x-pack/plugins/security_solution/server/lib/events/query.last_event_time.dsl.ts index 86491876673c99..6c443fed3c99d4 100644 --- a/x-pack/plugins/security_solution/server/lib/events/query.last_event_time.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/events/query.last_event_time.dsl.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import { isEmpty } from 'lodash/fp'; + import { LastEventTimeRequestOptions } from './types'; import { LastEventIndexKey } from '../../graphql/types'; import { assertUnreachable } from '../../utils/build_query'; @@ -16,6 +18,7 @@ export const buildLastEventTimeQuery = ({ indexKey, details, defaultIndex, + docValueFields, }: LastEventTimeRequestOptions) => { const indicesToQuery: EventIndices = { hosts: defaultIndex, @@ -35,6 +38,7 @@ export const buildLastEventTimeQuery = ({ index: indicesToQuery.network, ignoreUnavailable: true, body: { + ...(isEmpty(docValueFields) ? { docvalue_fields: docValueFields } : {}), aggregations: { last_seen_event: { max: { field: '@timestamp' } }, }, @@ -52,6 +56,7 @@ export const buildLastEventTimeQuery = ({ index: indicesToQuery.hosts, ignoreUnavailable: true, body: { + ...(isEmpty(docValueFields) ? { docvalue_fields: docValueFields } : {}), aggregations: { last_seen_event: { max: { field: '@timestamp' } }, }, @@ -69,6 +74,7 @@ export const buildLastEventTimeQuery = ({ index: indicesToQuery[indexKey], ignoreUnavailable: true, body: { + ...(isEmpty(docValueFields) ? { docvalue_fields: docValueFields } : {}), aggregations: { last_seen_event: { max: { field: '@timestamp' } }, }, diff --git a/x-pack/plugins/security_solution/server/lib/events/types.ts b/x-pack/plugins/security_solution/server/lib/events/types.ts index 3a4a8705f73873..aae2360e42e65d 100644 --- a/x-pack/plugins/security_solution/server/lib/events/types.ts +++ b/x-pack/plugins/security_solution/server/lib/events/types.ts @@ -11,6 +11,7 @@ import { SourceConfiguration, TimelineData, TimelineDetailsData, + DocValueFieldsInput, } from '../../graphql/types'; import { FrameworkRequest, RequestOptions, RequestOptionsPaginated } from '../framework'; import { SearchHit } from '../types'; @@ -61,13 +62,15 @@ export interface LastEventTimeRequestOptions { details: LastTimeDetails; sourceConfiguration: SourceConfiguration; defaultIndex: string[]; + docValueFields: DocValueFieldsInput[]; } export interface TimerangeFilter { range: { [timestamp: string]: { - gte: number; - lte: number; + gte: string; + lte: string; + format: string; }; }; } @@ -76,6 +79,7 @@ export interface RequestDetailsOptions { indexName: string; eventId: string; defaultIndex: string[]; + docValueFields?: DocValueFieldsInput[]; } interface EventsOverTimeHistogramData { diff --git a/x-pack/plugins/security_solution/server/lib/framework/types.ts b/x-pack/plugins/security_solution/server/lib/framework/types.ts index abe572df87063f..03c82ceb02e68d 100644 --- a/x-pack/plugins/security_solution/server/lib/framework/types.ts +++ b/x-pack/plugins/security_solution/server/lib/framework/types.ts @@ -18,6 +18,7 @@ import { TimerangeInput, Maybe, HistogramType, + DocValueFieldsInput, } from '../../graphql/types'; export * from '../../utils/typed_resolvers'; @@ -115,6 +116,7 @@ export interface RequestBasicOptions { timerange: TimerangeInput; filterQuery: ESQuery | undefined; defaultIndex: string[]; + docValueFields?: DocValueFieldsInput[]; } export interface MatrixHistogramRequestOptions extends RequestBasicOptions { diff --git a/x-pack/plugins/security_solution/server/lib/hosts/mock.ts b/x-pack/plugins/security_solution/server/lib/hosts/mock.ts index 0f6bc5c1b0e0c8..44767563c6b754 100644 --- a/x-pack/plugins/security_solution/server/lib/hosts/mock.ts +++ b/x-pack/plugins/security_solution/server/lib/hosts/mock.ts @@ -24,7 +24,7 @@ export const mockGetHostsOptions: HostsRequestOptions = { timestamp: '@timestamp', }, }, - timerange: { interval: '12h', to: 1554824274610, from: 1554737874610 }, + timerange: { interval: '12h', to: '2019-04-09T15:37:54.610Z', from: '2019-04-08T15:37:54.610Z' }, sort: { field: HostsFields.lastSeen, direction: Direction.asc }, pagination: { activePage: 0, @@ -295,7 +295,7 @@ export const mockGetHostOverviewOptions: HostOverviewRequestOptions = { timestamp: '@timestamp', }, }, - timerange: { interval: '12h', to: 1554824274610, from: 1554737874610 }, + timerange: { interval: '12h', to: '2019-04-09T15:37:54.610Z', from: '2019-04-08T15:37:54.610Z' }, defaultIndex: DEFAULT_INDEX_PATTERN, fields: [ '_id', diff --git a/x-pack/plugins/security_solution/server/lib/hosts/query.hosts.dsl.ts b/x-pack/plugins/security_solution/server/lib/hosts/query.hosts.dsl.ts index 70f57769362f58..013afd5cd58f5a 100644 --- a/x-pack/plugins/security_solution/server/lib/hosts/query.hosts.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/hosts/query.hosts.dsl.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import { isEmpty } from 'lodash/fp'; + import { Direction, HostsFields, HostsSortField } from '../../graphql/types'; import { assertUnreachable, createQueryFilterClauses } from '../../utils/build_query'; @@ -11,6 +13,7 @@ import { HostsRequestOptions } from '.'; export const buildHostsQuery = ({ defaultIndex, + docValueFields, fields, filterQuery, pagination: { querySize }, @@ -27,6 +30,7 @@ export const buildHostsQuery = ({ [timestamp]: { gte: from, lte: to, + format: 'strict_date_optional_time', }, }, }, @@ -39,6 +43,7 @@ export const buildHostsQuery = ({ index: defaultIndex, ignoreUnavailable: true, body: { + ...(isEmpty(docValueFields) ? { docvalue_fields: docValueFields } : {}), aggregations: { ...agg, host_data: { diff --git a/x-pack/plugins/security_solution/server/lib/hosts/query.last_first_seen_host.dsl.ts b/x-pack/plugins/security_solution/server/lib/hosts/query.last_first_seen_host.dsl.ts index d7ab22100b2460..3bdaee58917ea0 100644 --- a/x-pack/plugins/security_solution/server/lib/hosts/query.last_first_seen_host.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/hosts/query.last_first_seen_host.dsl.ts @@ -4,11 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ +import { isEmpty } from 'lodash/fp'; import { HostLastFirstSeenRequestOptions } from './types'; export const buildLastFirstSeenHostQuery = ({ hostName, defaultIndex, + docValueFields, }: HostLastFirstSeenRequestOptions) => { const filter = [{ term: { 'host.name': hostName } }]; @@ -17,6 +19,7 @@ export const buildLastFirstSeenHostQuery = ({ index: defaultIndex, ignoreUnavailable: true, body: { + ...(isEmpty(docValueFields) ? { docvalue_fields: docValueFields } : {}), aggregations: { firstSeen: { min: { field: '@timestamp' } }, lastSeen: { max: { field: '@timestamp' } }, diff --git a/x-pack/plugins/security_solution/server/lib/hosts/types.ts b/x-pack/plugins/security_solution/server/lib/hosts/types.ts index e52cfe9d7feebd..fc621f81a4f5fc 100644 --- a/x-pack/plugins/security_solution/server/lib/hosts/types.ts +++ b/x-pack/plugins/security_solution/server/lib/hosts/types.ts @@ -14,6 +14,7 @@ import { OsEcsFields, SourceConfiguration, TimerangeInput, + DocValueFieldsInput, } from '../../graphql/types'; import { FrameworkRequest, RequestOptionsPaginated } from '../framework'; import { Hit, Hits, SearchHit, TotalValue } from '../types'; @@ -50,6 +51,7 @@ export interface HostLastFirstSeenRequestOptions { hostName: string; sourceConfiguration: SourceConfiguration; defaultIndex: string[]; + docValueFields?: DocValueFieldsInput[]; } export interface HostOverviewRequestOptions extends HostLastFirstSeenRequestOptions { diff --git a/x-pack/plugins/security_solution/server/lib/ip_details/query_overview.dsl.ts b/x-pack/plugins/security_solution/server/lib/ip_details/query_overview.dsl.ts index 5803b832a334b2..d9c8f32d0b465c 100644 --- a/x-pack/plugins/security_solution/server/lib/ip_details/query_overview.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/ip_details/query_overview.dsl.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { isEmpty } from 'lodash/fp'; import { IpOverviewRequestOptions } from './index'; const getAggs = (type: string, ip: string) => { @@ -95,12 +96,17 @@ const getHostAggs = (ip: string) => { }; }; -export const buildOverviewQuery = ({ defaultIndex, ip }: IpOverviewRequestOptions) => { +export const buildOverviewQuery = ({ + defaultIndex, + docValueFields, + ip, +}: IpOverviewRequestOptions) => { const dslQuery = { allowNoIndices: true, index: defaultIndex, ignoreUnavailable: true, body: { + ...(isEmpty(docValueFields) ? { docvalue_fields: docValueFields } : {}), aggs: { ...getAggs('source', ip), ...getAggs('destination', ip), @@ -115,5 +121,6 @@ export const buildOverviewQuery = ({ defaultIndex, ip }: IpOverviewRequestOption track_total_hits: false, }, }; + return dslQuery; }; diff --git a/x-pack/plugins/security_solution/server/lib/ip_details/query_users.dsl.ts b/x-pack/plugins/security_solution/server/lib/ip_details/query_users.dsl.ts index b2453325256943..10678dc033eb5d 100644 --- a/x-pack/plugins/security_solution/server/lib/ip_details/query_users.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/ip_details/query_users.dsl.ts @@ -23,7 +23,11 @@ export const buildUsersQuery = ({ }: UsersRequestOptions) => { const filter = [ ...createQueryFilterClauses(filterQuery), - { range: { [timestamp]: { gte: from, lte: to } } }, + { + range: { + [timestamp]: { gte: from, lte: to, format: 'strict_date_optional_time' }, + }, + }, { term: { [`${flowTarget}.ip`]: ip } }, ]; diff --git a/x-pack/plugins/security_solution/server/lib/kpi_hosts/mock.ts b/x-pack/plugins/security_solution/server/lib/kpi_hosts/mock.ts index a5affea2842a6c..876d2f9c16bed6 100644 --- a/x-pack/plugins/security_solution/server/lib/kpi_hosts/mock.ts +++ b/x-pack/plugins/security_solution/server/lib/kpi_hosts/mock.ts @@ -7,8 +7,8 @@ import { DEFAULT_INDEX_PATTERN } from '../../../common/constants'; import { RequestBasicOptions } from '../framework/types'; -const FROM = new Date('2019-05-03T13:24:00.660Z').valueOf(); -const TO = new Date('2019-05-04T13:24:00.660Z').valueOf(); +const FROM = '2019-05-03T13:24:00.660Z'; +const TO = '2019-05-04T13:24:00.660Z'; export const mockKpiHostsOptions: RequestBasicOptions = { defaultIndex: DEFAULT_INDEX_PATTERN, diff --git a/x-pack/plugins/security_solution/server/lib/kpi_hosts/query_authentication.dsl.ts b/x-pack/plugins/security_solution/server/lib/kpi_hosts/query_authentication.dsl.ts index 0b7803d0071947..ee9e6cd5a66c5c 100644 --- a/x-pack/plugins/security_solution/server/lib/kpi_hosts/query_authentication.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/kpi_hosts/query_authentication.dsl.ts @@ -33,6 +33,7 @@ export const buildAuthQuery = ({ [timestamp]: { gte: from, lte: to, + format: 'strict_date_optional_time', }, }, }, diff --git a/x-pack/plugins/security_solution/server/lib/kpi_hosts/query_hosts.dsl.ts b/x-pack/plugins/security_solution/server/lib/kpi_hosts/query_hosts.dsl.ts index 87ebf0cf0e6e7a..0c1d7d4ae9de7d 100644 --- a/x-pack/plugins/security_solution/server/lib/kpi_hosts/query_hosts.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/kpi_hosts/query_hosts.dsl.ts @@ -22,6 +22,7 @@ export const buildHostsQuery = ({ [timestamp]: { gte: from, lte: to, + format: 'strict_date_optional_time', }, }, }, diff --git a/x-pack/plugins/security_solution/server/lib/kpi_hosts/query_unique_ips.dsl.ts b/x-pack/plugins/security_solution/server/lib/kpi_hosts/query_unique_ips.dsl.ts index 72833aaf9ea5bb..9813f73101235d 100644 --- a/x-pack/plugins/security_solution/server/lib/kpi_hosts/query_unique_ips.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/kpi_hosts/query_unique_ips.dsl.ts @@ -22,6 +22,7 @@ export const buildUniqueIpsQuery = ({ [timestamp]: { gte: from, lte: to, + format: 'strict_date_optional_time', }, }, }, diff --git a/x-pack/plugins/security_solution/server/lib/kpi_network/mock.ts b/x-pack/plugins/security_solution/server/lib/kpi_network/mock.ts index cc0849ccdf1d24..fc9b64ae0746f2 100644 --- a/x-pack/plugins/security_solution/server/lib/kpi_network/mock.ts +++ b/x-pack/plugins/security_solution/server/lib/kpi_network/mock.ts @@ -19,7 +19,7 @@ export const mockOptions: RequestBasicOptions = { timestamp: '@timestamp', }, }, - timerange: { interval: '12h', to: 1549852006071, from: 1549765606071 }, + timerange: { interval: '12h', to: '2019-02-11T02:26:46.071Z', from: '2019-02-10T02:26:46.071Z' }, filterQuery: {}, }; @@ -28,7 +28,11 @@ export const mockRequest = { operationName: 'GetKpiNetworkQuery', variables: { sourceId: 'default', - timerange: { interval: '12h', from: 1557445721842, to: 1557532121842 }, + timerange: { + interval: '12h', + from: '2019-05-09T23:48:41.842Z', + to: '2019-05-10T23:48:41.842Z', + }, filterQuery: '', }, query: diff --git a/x-pack/plugins/security_solution/server/lib/kpi_network/query_dns.dsl.ts b/x-pack/plugins/security_solution/server/lib/kpi_network/query_dns.dsl.ts index 01771ad973b5d3..b3dba9b1d0fab9 100644 --- a/x-pack/plugins/security_solution/server/lib/kpi_network/query_dns.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/kpi_network/query_dns.dsl.ts @@ -51,6 +51,7 @@ export const buildDnsQuery = ({ [timestamp]: { gte: from, lte: to, + format: 'strict_date_optional_time', }, }, }, diff --git a/x-pack/plugins/security_solution/server/lib/kpi_network/query_network_events.ts b/x-pack/plugins/security_solution/server/lib/kpi_network/query_network_events.ts index 1a87aff047a257..17f705fe98d031 100644 --- a/x-pack/plugins/security_solution/server/lib/kpi_network/query_network_events.ts +++ b/x-pack/plugins/security_solution/server/lib/kpi_network/query_network_events.ts @@ -25,6 +25,7 @@ export const buildNetworkEventsQuery = ({ [timestamp]: { gte: from, lte: to, + format: 'strict_date_optional_time', }, }, }, diff --git a/x-pack/plugins/security_solution/server/lib/kpi_network/query_tls_handshakes.dsl.ts b/x-pack/plugins/security_solution/server/lib/kpi_network/query_tls_handshakes.dsl.ts index 09bc0eae642e44..5032863e7d324d 100644 --- a/x-pack/plugins/security_solution/server/lib/kpi_network/query_tls_handshakes.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/kpi_network/query_tls_handshakes.dsl.ts @@ -51,6 +51,7 @@ export const buildTlsHandshakeQuery = ({ [timestamp]: { gte: from, lte: to, + format: 'strict_date_optional_time', }, }, }, diff --git a/x-pack/plugins/security_solution/server/lib/kpi_network/query_unique_flow.ts b/x-pack/plugins/security_solution/server/lib/kpi_network/query_unique_flow.ts index 4581b889cc9ef5..fb717df2b4608d 100644 --- a/x-pack/plugins/security_solution/server/lib/kpi_network/query_unique_flow.ts +++ b/x-pack/plugins/security_solution/server/lib/kpi_network/query_unique_flow.ts @@ -25,6 +25,7 @@ export const buildUniqueFlowIdsQuery = ({ [timestamp]: { gte: from, lte: to, + format: 'strict_date_optional_time', }, }, }, diff --git a/x-pack/plugins/security_solution/server/lib/kpi_network/query_unique_private_ips.dsl.ts b/x-pack/plugins/security_solution/server/lib/kpi_network/query_unique_private_ips.dsl.ts index f12ab2a3072ae9..77d6efdcfdaa0c 100644 --- a/x-pack/plugins/security_solution/server/lib/kpi_network/query_unique_private_ips.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/kpi_network/query_unique_private_ips.dsl.ts @@ -77,6 +77,7 @@ export const buildUniquePrvateIpQuery = ({ [timestamp]: { gte: from, lte: to, + format: 'strict_date_optional_time', }, }, }, diff --git a/x-pack/plugins/security_solution/server/lib/matrix_histogram/query.anomalies_over_time.dsl.ts b/x-pack/plugins/security_solution/server/lib/matrix_histogram/query.anomalies_over_time.dsl.ts index 38e8387f43ffde..fb4e666cda964a 100644 --- a/x-pack/plugins/security_solution/server/lib/matrix_histogram/query.anomalies_over_time.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/matrix_histogram/query.anomalies_over_time.dsl.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import moment from 'moment'; + import { createQueryFilterClauses, calculateTimeSeriesInterval } from '../../utils/build_query'; import { MatrixHistogramRequestOptions } from '../framework'; @@ -20,6 +22,7 @@ export const buildAnomaliesOverTimeQuery = ({ timestamp: { gte: from, lte: to, + format: 'strict_date_optional_time', }, }, }, @@ -34,8 +37,8 @@ export const buildAnomaliesOverTimeQuery = ({ fixed_interval: interval, min_doc_count: 0, extended_bounds: { - min: from, - max: to, + min: moment(from).valueOf(), + max: moment(to).valueOf(), }, }, }; diff --git a/x-pack/plugins/security_solution/server/lib/matrix_histogram/query.authentications_over_time.dsl.ts b/x-pack/plugins/security_solution/server/lib/matrix_histogram/query.authentications_over_time.dsl.ts index 34a3804f974ded..174cc907214a9c 100644 --- a/x-pack/plugins/security_solution/server/lib/matrix_histogram/query.authentications_over_time.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/matrix_histogram/query.authentications_over_time.dsl.ts @@ -3,6 +3,8 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ +import moment from 'moment'; + import { createQueryFilterClauses, calculateTimeSeriesInterval } from '../../utils/build_query'; import { MatrixHistogramRequestOptions } from '../framework'; @@ -33,6 +35,7 @@ export const buildAuthenticationsOverTimeQuery = ({ [timestamp]: { gte: from, lte: to, + format: 'strict_date_optional_time', }, }, }, @@ -47,8 +50,8 @@ export const buildAuthenticationsOverTimeQuery = ({ fixed_interval: interval, min_doc_count: 0, extended_bounds: { - min: from, - max: to, + min: moment(from).valueOf(), + max: moment(to).valueOf(), }, }, }; diff --git a/x-pack/plugins/security_solution/server/lib/matrix_histogram/query.events_over_time.dsl.ts b/x-pack/plugins/security_solution/server/lib/matrix_histogram/query.events_over_time.dsl.ts index 63649a1064b025..fa7c1b9e55b9e9 100644 --- a/x-pack/plugins/security_solution/server/lib/matrix_histogram/query.events_over_time.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/matrix_histogram/query.events_over_time.dsl.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import moment from 'moment'; + import { showAllOthersBucket } from '../../../common/constants'; import { createQueryFilterClauses, calculateTimeSeriesInterval } from '../../utils/build_query'; import { MatrixHistogramRequestOptions } from '../framework'; @@ -26,6 +28,7 @@ export const buildEventsOverTimeQuery = ({ [timestamp]: { gte: from, lte: to, + format: 'strict_date_optional_time', }, }, }, @@ -40,8 +43,8 @@ export const buildEventsOverTimeQuery = ({ fixed_interval: interval, min_doc_count: 0, extended_bounds: { - min: from, - max: to, + min: moment(from).valueOf(), + max: moment(to).valueOf(), }, }, }; diff --git a/x-pack/plugins/security_solution/server/lib/matrix_histogram/query_alerts.dsl.ts b/x-pack/plugins/security_solution/server/lib/matrix_histogram/query_alerts.dsl.ts index 4963f01d67a4f0..dd451096724807 100644 --- a/x-pack/plugins/security_solution/server/lib/matrix_histogram/query_alerts.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/matrix_histogram/query_alerts.dsl.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import moment from 'moment'; + import { createQueryFilterClauses, calculateTimeSeriesInterval } from '../../utils/build_query'; import { buildTimelineQuery } from '../events/query.dsl'; import { RequestOptions, MatrixHistogramRequestOptions } from '../framework'; @@ -62,6 +64,7 @@ export const buildAlertsHistogramQuery = ({ [timestamp]: { gte: from, lte: to, + format: 'strict_date_optional_time', }, }, }, @@ -76,8 +79,8 @@ export const buildAlertsHistogramQuery = ({ fixed_interval: interval, min_doc_count: 0, extended_bounds: { - min: from, - max: to, + min: moment(from).valueOf(), + max: moment(to).valueOf(), }, }, }; diff --git a/x-pack/plugins/security_solution/server/lib/matrix_histogram/query_dns_histogram.dsl.ts b/x-pack/plugins/security_solution/server/lib/matrix_histogram/query_dns_histogram.dsl.ts index a6c75fe01eb151..7e712639889572 100644 --- a/x-pack/plugins/security_solution/server/lib/matrix_histogram/query_dns_histogram.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/matrix_histogram/query_dns_histogram.dsl.ts @@ -23,6 +23,7 @@ export const buildDnsHistogramQuery = ({ [timestamp]: { gte: from, lte: to, + format: 'strict_date_optional_time', }, }, }, diff --git a/x-pack/plugins/security_solution/server/lib/network/mock.ts b/x-pack/plugins/security_solution/server/lib/network/mock.ts index 38e82a4f19dca9..b421f7af566039 100644 --- a/x-pack/plugins/security_solution/server/lib/network/mock.ts +++ b/x-pack/plugins/security_solution/server/lib/network/mock.ts @@ -21,7 +21,7 @@ export const mockOptions: NetworkTopNFlowRequestOptions = { timestamp: '@timestamp', }, }, - timerange: { interval: '12h', to: 1549852006071, from: 1549765606071 }, + timerange: { interval: '12h', to: '2019-02-11T02:26:46.071Z', from: '2019-02-11T02:26:46.071Z' }, pagination: { activePage: 0, cursorStart: 0, diff --git a/x-pack/plugins/security_solution/server/lib/network/query_dns.dsl.ts b/x-pack/plugins/security_solution/server/lib/network/query_dns.dsl.ts index 96b5d260b15443..e7c86e1d3d66be 100644 --- a/x-pack/plugins/security_solution/server/lib/network/query_dns.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/network/query_dns.dsl.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import { isEmpty } from 'lodash/fp'; + import { Direction, NetworkDnsFields, NetworkDnsSortField } from '../../graphql/types'; import { assertUnreachable, createQueryFilterClauses } from '../../utils/build_query'; @@ -57,6 +59,7 @@ const createIncludePTRFilter = (isPtrIncluded: boolean) => export const buildDnsQuery = ({ defaultIndex, + docValueFields, filterQuery, isPtrIncluded, networkDnsSortField, @@ -74,6 +77,7 @@ export const buildDnsQuery = ({ [timestamp]: { gte: from, lte: to, + format: 'strict_date_optional_time', }, }, }, @@ -84,6 +88,7 @@ export const buildDnsQuery = ({ index: defaultIndex, ignoreUnavailable: true, body: { + ...(isEmpty(docValueFields) ? { docvalue_fields: docValueFields } : {}), aggregations: { ...getCountAgg(), dns_name_query_count: { diff --git a/x-pack/plugins/security_solution/server/lib/network/query_http.dsl.ts b/x-pack/plugins/security_solution/server/lib/network/query_http.dsl.ts index 3e33b5af80a855..a2d1963414be1a 100644 --- a/x-pack/plugins/security_solution/server/lib/network/query_http.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/network/query_http.dsl.ts @@ -29,7 +29,11 @@ export const buildHttpQuery = ({ }: NetworkHttpRequestOptions) => { const filter = [ ...createQueryFilterClauses(filterQuery), - { range: { [timestamp]: { gte: from, lte: to } } }, + { + range: { + [timestamp]: { gte: from, lte: to, format: 'strict_date_optional_time' }, + }, + }, { exists: { field: 'http.request.method' } }, ]; diff --git a/x-pack/plugins/security_solution/server/lib/network/query_top_countries.dsl.ts b/x-pack/plugins/security_solution/server/lib/network/query_top_countries.dsl.ts index 40bee7eee81554..93ffc35161fa96 100644 --- a/x-pack/plugins/security_solution/server/lib/network/query_top_countries.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/network/query_top_countries.dsl.ts @@ -36,7 +36,11 @@ export const buildTopCountriesQuery = ({ }: NetworkTopCountriesRequestOptions) => { const filter = [ ...createQueryFilterClauses(filterQuery), - { range: { [timestamp]: { gte: from, lte: to } } }, + { + range: { + [timestamp]: { gte: from, lte: to, format: 'strict_date_optional_time' }, + }, + }, ]; const dslQuery = { diff --git a/x-pack/plugins/security_solution/server/lib/network/query_top_n_flow.dsl.ts b/x-pack/plugins/security_solution/server/lib/network/query_top_n_flow.dsl.ts index 47bbabf5505cad..7cb8b76e7b5244 100644 --- a/x-pack/plugins/security_solution/server/lib/network/query_top_n_flow.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/network/query_top_n_flow.dsl.ts @@ -36,7 +36,11 @@ export const buildTopNFlowQuery = ({ }: NetworkTopNFlowRequestOptions) => { const filter = [ ...createQueryFilterClauses(filterQuery), - { range: { [timestamp]: { gte: from, lte: to } } }, + { + range: { + [timestamp]: { gte: from, lte: to, format: 'strict_date_optional_time' }, + }, + }, ]; const dslQuery = { diff --git a/x-pack/plugins/security_solution/server/lib/overview/mock.ts b/x-pack/plugins/security_solution/server/lib/overview/mock.ts index 51d8a258569a8b..2621c795ecd6b8 100644 --- a/x-pack/plugins/security_solution/server/lib/overview/mock.ts +++ b/x-pack/plugins/security_solution/server/lib/overview/mock.ts @@ -19,7 +19,7 @@ export const mockOptionsNetwork: RequestBasicOptions = { timestamp: '@timestamp', }, }, - timerange: { interval: '12h', to: 1549852006071, from: 1549765606071 }, + timerange: { interval: '12h', to: '2019-02-11T02:26:46.071Z', from: '2019-02-10T02:26:46.071Z' }, filterQuery: {}, }; @@ -28,7 +28,11 @@ export const mockRequestNetwork = { operationName: 'GetOverviewNetworkQuery', variables: { sourceId: 'default', - timerange: { interval: '12h', from: 1549765830772, to: 1549852230772 }, + timerange: { + interval: '12h', + from: '2019-02-10T02:30:30.772Z', + to: '2019-02-11T02:30:30.772Z', + }, filterQuery: '', }, query: @@ -90,7 +94,7 @@ export const mockOptionsHost: RequestBasicOptions = { timestamp: '@timestamp', }, }, - timerange: { interval: '12h', to: 1549852006071, from: 1549765606071 }, + timerange: { interval: '12h', to: '2019-02-11T02:26:46.071Z', from: '2019-02-10T02:26:46.071Z' }, filterQuery: {}, }; @@ -99,7 +103,11 @@ export const mockRequestHost = { operationName: 'GetOverviewHostQuery', variables: { sourceId: 'default', - timerange: { interval: '12h', from: 1549765830772, to: 1549852230772 }, + timerange: { + interval: '12h', + from: '2019-02-10T02:30:30.772Z', + to: '2019-02-11T02:30:30.772Z', + }, filterQuery: '', }, query: diff --git a/x-pack/plugins/security_solution/server/lib/overview/query.dsl.ts b/x-pack/plugins/security_solution/server/lib/overview/query.dsl.ts index 30656c011ee21d..8ac8233a86b82f 100644 --- a/x-pack/plugins/security_solution/server/lib/overview/query.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/overview/query.dsl.ts @@ -21,6 +21,7 @@ export const buildOverviewNetworkQuery = ({ [timestamp]: { gte: from, lte: to, + format: 'strict_date_optional_time', }, }, }, @@ -120,6 +121,7 @@ export const buildOverviewHostQuery = ({ [timestamp]: { gte: from, lte: to, + format: 'strict_date_optional_time', }, }, }, diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/__mocks__/import_timelines.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/__mocks__/import_timelines.ts index 2afe3197d6d645..0b10018de5bba5 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/__mocks__/import_timelines.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/__mocks__/import_timelines.ts @@ -21,7 +21,7 @@ export const mockParsedObjects = [ kqlMode: 'filter', kqlQuery: { filterQuery: [Object] }, title: 'My duplicate timeline', - dateRange: { start: 1584523907294, end: 1584610307294 }, + dateRange: { start: '2020-03-18T09:31:47.294Z', end: '2020-03-19T09:31:47.294Z' }, savedQueryId: null, sort: { columnId: '@timestamp', sortDirection: 'desc' }, created: 1584828930463, @@ -80,7 +80,7 @@ export const mockUniqueParsedObjects = [ kqlMode: 'filter', kqlQuery: { filterQuery: [] }, title: 'My duplicate timeline', - dateRange: { start: 1584523907294, end: 1584610307294 }, + dateRange: { start: '2020-03-18T09:31:47.294Z', end: '2020-03-19T09:31:47.294Z' }, savedQueryId: null, sort: { columnId: '@timestamp', sortDirection: 'desc' }, created: 1584828930463, @@ -139,7 +139,7 @@ export const mockGetTimelineValue = { kqlQuery: { filterQuery: [] }, title: 'My duplicate timeline', timelineType: TimelineType.default, - dateRange: { start: 1584523907294, end: 1584610307294 }, + dateRange: { start: '2020-03-18T09:31:47.294Z', end: '2020-03-19T09:31:47.294Z' }, savedQueryId: null, sort: { columnId: '@timestamp', sortDirection: 'desc' }, created: 1584828930463, @@ -176,7 +176,7 @@ export const mockGetDraftTimelineValue = { kqlMode: 'filter', kqlQuery: { filterQuery: [] }, title: 'My duplicate timeline', - dateRange: { start: 1584523907294, end: 1584610307294 }, + dateRange: { start: '2020-03-18T09:31:47.294Z', end: '2020-03-19T09:31:47.294Z' }, savedQueryId: null, sort: { columnId: '@timestamp', sortDirection: 'desc' }, created: 1584828930463, @@ -236,7 +236,7 @@ export const mockCreatedTimeline = { kqlMode: 'filter', kqlQuery: { filterQuery: [] }, title: 'My duplicate timeline', - dateRange: { start: 1584523907294, end: 1584610307294 }, + dateRange: { start: '2020-03-18T09:31:47.294Z', end: '2020-03-19T09:31:47.294Z' }, savedQueryId: null, sort: { columnId: '@timestamp', sortDirection: 'desc' }, created: 1584828930463, diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/__mocks__/request_responses.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/__mocks__/request_responses.ts index a314d5fb36c6df..e3aeff280678ff 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/__mocks__/request_responses.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/__mocks__/request_responses.ts @@ -65,7 +65,7 @@ export const inputTimeline: SavedTimeline = { timelineType: TimelineType.default, templateTimelineId: null, templateTimelineVersion: 1, - dateRange: { start: 1585227005527, end: 1585313405527 }, + dateRange: { start: '2020-03-26T12:50:05.527Z', end: '2020-03-27T12:50:05.527Z' }, savedQueryId: null, sort: { columnId: '@timestamp', sortDirection: 'desc' }, }; @@ -281,7 +281,7 @@ export const mockTimelines = () => ({ }, }, title: 'test no.2', - dateRange: { start: 1582538951145, end: 1582625351145 }, + dateRange: { start: '2020-02-24T10:09:11.145Z', end: '2020-02-25T10:09:11.145Z' }, savedQueryId: null, sort: { columnId: '@timestamp', sortDirection: 'desc' }, created: 1582625382448, @@ -363,7 +363,7 @@ export const mockTimelines = () => ({ }, }, title: 'test no.3', - dateRange: { start: 1582538951145, end: 1582625351145 }, + dateRange: { start: '2020-02-24T10:09:11.145Z', end: '2020-02-25T10:09:11.145Z' }, savedQueryId: null, sort: { columnId: '@timestamp', sortDirection: 'desc' }, created: 1582642817439, diff --git a/x-pack/plugins/security_solution/server/lib/tls/mock.ts b/x-pack/plugins/security_solution/server/lib/tls/mock.ts index b97a6fa509ef28..62d5e1e61570a7 100644 --- a/x-pack/plugins/security_solution/server/lib/tls/mock.ts +++ b/x-pack/plugins/security_solution/server/lib/tls/mock.ts @@ -458,7 +458,7 @@ export const mockOptions = { timestamp: '@timestamp', }, }, - timerange: { interval: '12h', to: 1570801871626, from: 1570715471626 }, + timerange: { interval: '12h', to: '2019-10-11T13:51:11.626Z', from: '2019-10-10T13:51:11.626Z' }, pagination: { activePage: 0, cursorStart: 0, fakePossibleCount: 50, querySize: 10 }, filterQuery: {}, fields: [ diff --git a/x-pack/plugins/security_solution/server/lib/tls/query_tls.dsl.ts b/x-pack/plugins/security_solution/server/lib/tls/query_tls.dsl.ts index bc65be642dabc0..82f16ff58d135e 100644 --- a/x-pack/plugins/security_solution/server/lib/tls/query_tls.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/tls/query_tls.dsl.ts @@ -62,7 +62,11 @@ export const buildTlsQuery = ({ }: TlsRequestOptions) => { const defaultFilter = [ ...createQueryFilterClauses(filterQuery), - { range: { [timestamp]: { gte: from, lte: to } } }, + { + range: { + [timestamp]: { gte: from, lte: to, format: 'strict_date_optional_time' }, + }, + }, ]; const filter = ip ? [...defaultFilter, { term: { [`${flowTarget}.ip`]: ip } }] : defaultFilter; diff --git a/x-pack/plugins/security_solution/server/lib/uncommon_processes/query.dsl.ts b/x-pack/plugins/security_solution/server/lib/uncommon_processes/query.dsl.ts index 24cae53d5d3534..4563c769cdc31b 100644 --- a/x-pack/plugins/security_solution/server/lib/uncommon_processes/query.dsl.ts +++ b/x-pack/plugins/security_solution/server/lib/uncommon_processes/query.dsl.ts @@ -28,6 +28,7 @@ export const buildQuery = ({ [timestamp]: { gte: from, lte: to, + format: 'strict_date_optional_time', }, }, }, diff --git a/x-pack/plugins/security_solution/server/utils/build_query/calculate_timeseries_interval.ts b/x-pack/plugins/security_solution/server/utils/build_query/calculate_timeseries_interval.ts index 78aadf75e54c36..ded37db677d6d3 100644 --- a/x-pack/plugins/security_solution/server/utils/build_query/calculate_timeseries_interval.ts +++ b/x-pack/plugins/security_solution/server/utils/build_query/calculate_timeseries_interval.ts @@ -89,6 +89,6 @@ export const calculateAuto = { }), }; -export const calculateTimeSeriesInterval = (from: number, to: number) => { - return `${Math.floor((to - from) / 32)}ms`; +export const calculateTimeSeriesInterval = (from: string, to: string) => { + return `${Math.floor(moment(to).diff(moment(from)) / 32)}ms`; }; diff --git a/x-pack/plugins/security_solution/server/utils/build_query/create_options.test.ts b/x-pack/plugins/security_solution/server/utils/build_query/create_options.test.ts index 5ca67ad6ae51f7..e83ca7418ad3d4 100644 --- a/x-pack/plugins/security_solution/server/utils/build_query/create_options.test.ts +++ b/x-pack/plugins/security_solution/server/utils/build_query/create_options.test.ts @@ -34,9 +34,19 @@ describe('createOptions', () => { pagination: { limit: 5, }, + docValueFields: [ + { + field: '@timestamp', + format: 'date_time', + }, + { + field: 'event.end', + format: 'date_time', + }, + ], timerange: { - from: 10, - to: 0, + from: '2020-07-08T08:00:00.000Z', + to: '2020-07-08T20:00:00.000Z', interval: '12 hours ago', }, sortField: { sortFieldId: 'sort-1', direction: Direction.asc }, @@ -73,10 +83,20 @@ describe('createOptions', () => { limit: 5, }, filterQuery: {}, + docValueFields: [ + { + field: '@timestamp', + format: 'date_time', + }, + { + field: 'event.end', + format: 'date_time', + }, + ], fields: [], timerange: { - from: 10, - to: 0, + from: '2020-07-08T08:00:00.000Z', + to: '2020-07-08T20:00:00.000Z', interval: '12 hours ago', }, }; @@ -102,10 +122,51 @@ describe('createOptions', () => { limit: 5, }, filterQuery: {}, + docValueFields: [ + { + field: '@timestamp', + format: 'date_time', + }, + { + field: 'event.end', + format: 'date_time', + }, + ], + fields: [], + timerange: { + from: '2020-07-08T08:00:00.000Z', + to: '2020-07-08T20:00:00.000Z', + interval: '12 hours ago', + }, + }; + expect(options).toEqual(expected); + }); + + test('should create options given all input except docValueFields', () => { + const argsWithoutSort: Args = omit('docValueFields', args); + const options = createOptions(source, argsWithoutSort, info); + const expected: RequestOptions = { + defaultIndex: DEFAULT_INDEX_PATTERN, + sourceConfiguration: { + fields: { + host: 'host-1', + container: 'container-1', + message: ['message-1'], + pod: 'pod-1', + tiebreaker: 'tiebreaker', + timestamp: 'timestamp-1', + }, + }, + sortField: { sortFieldId: 'sort-1', direction: Direction.asc }, + pagination: { + limit: 5, + }, + filterQuery: {}, + docValueFields: [], fields: [], timerange: { - from: 10, - to: 0, + from: '2020-07-08T08:00:00.000Z', + to: '2020-07-08T20:00:00.000Z', interval: '12 hours ago', }, }; diff --git a/x-pack/plugins/security_solution/server/utils/build_query/create_options.ts b/x-pack/plugins/security_solution/server/utils/build_query/create_options.ts index 5a5aff2a2d54e0..5895c0a4041361 100644 --- a/x-pack/plugins/security_solution/server/utils/build_query/create_options.ts +++ b/x-pack/plugins/security_solution/server/utils/build_query/create_options.ts @@ -13,6 +13,7 @@ import { SortField, Source, TimerangeInput, + DocValueFieldsInput, } from '../../graphql/types'; import { RequestOptions, RequestOptionsPaginated } from '../../lib/framework'; import { parseFilterQuery } from '../serialized_query'; @@ -32,6 +33,7 @@ export interface Args { filterQuery?: string | null; sortField?: SortField | null; defaultIndex: string[]; + docValueFields?: DocValueFieldsInput[]; } export interface ArgsPaginated { timerange?: TimerangeInput | null; @@ -39,6 +41,7 @@ export interface ArgsPaginated { filterQuery?: string | null; sortField?: SortField | null; defaultIndex: string[]; + docValueFields?: DocValueFieldsInput[]; } export const createOptions = ( @@ -50,6 +53,7 @@ export const createOptions = ( const fields = getFields(getOr([], 'fieldNodes[0]', info)); return { defaultIndex: args.defaultIndex, + docValueFields: args.docValueFields ?? [], sourceConfiguration: source.configuration, timerange: args.timerange!, pagination: args.pagination!, @@ -70,6 +74,7 @@ export const createOptionsPaginated = ( const fields = getFields(getOr([], 'fieldNodes[0]', info)); return { defaultIndex: args.defaultIndex, + docValueFields: args.docValueFields ?? [], sourceConfiguration: source.configuration, timerange: args.timerange!, pagination: args.pagination!, diff --git a/x-pack/test/api_integration/apis/security_solution/authentications.ts b/x-pack/test/api_integration/apis/security_solution/authentications.ts index 90784ec786d48f..277ac7316e92dd 100644 --- a/x-pack/test/api_integration/apis/security_solution/authentications.ts +++ b/x-pack/test/api_integration/apis/security_solution/authentications.ts @@ -10,8 +10,8 @@ import { authenticationsQuery } from '../../../../plugins/security_solution/publ import { GetAuthenticationsQuery } from '../../../../plugins/security_solution/public/graphql/types'; import { FtrProviderContext } from '../../ftr_provider_context'; -const FROM = new Date('2000-01-01T00:00:00.000Z').valueOf(); -const TO = new Date('3000-01-01T00:00:00.000Z').valueOf(); +const FROM = '2000-01-01T00:00:00.000Z'; +const TO = '3000-01-01T00:00:00.000Z'; // typical values that have to change after an update from "scripts/es_archiver" const HOST_NAME = 'zeek-newyork-sha-aa8df15'; @@ -44,6 +44,7 @@ export default function ({ getService }: FtrProviderContext) { querySize: 1, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }) @@ -73,6 +74,7 @@ export default function ({ getService }: FtrProviderContext) { querySize: 2, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }) diff --git a/x-pack/test/api_integration/apis/security_solution/hosts.ts b/x-pack/test/api_integration/apis/security_solution/hosts.ts index 9ee85f7ff03dc2..2904935719d2ca 100644 --- a/x-pack/test/api_integration/apis/security_solution/hosts.ts +++ b/x-pack/test/api_integration/apis/security_solution/hosts.ts @@ -18,8 +18,8 @@ import { HostFirstLastSeenGqlQuery } from '../../../../plugins/security_solution import { HostsTableQuery } from '../../../../plugins/security_solution/public/hosts/containers/hosts/hosts_table.gql_query'; import { FtrProviderContext } from '../../ftr_provider_context'; -const FROM = new Date('2000-01-01T00:00:00.000Z').valueOf(); -const TO = new Date('3000-01-01T00:00:00.000Z').valueOf(); +const FROM = '2000-01-01T00:00:00.000Z'; +const TO = '3000-01-01T00:00:00.000Z'; // typical values that have to change after an update from "scripts/es_archiver" const HOST_NAME = 'Ubuntu'; @@ -47,6 +47,7 @@ export default function ({ getService }: FtrProviderContext) { from: FROM, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], sort: { field: HostsFields.lastSeen, direction: Direction.asc, @@ -84,6 +85,7 @@ export default function ({ getService }: FtrProviderContext) { direction: Direction.asc, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], pagination: { activePage: 2, cursorStart: 1, @@ -150,6 +152,7 @@ export default function ({ getService }: FtrProviderContext) { from: FROM, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }) @@ -167,6 +170,7 @@ export default function ({ getService }: FtrProviderContext) { sourceId: 'default', hostName: 'zeek-sensor-san-francisco', defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], }, }) .then((resp) => { diff --git a/x-pack/test/api_integration/apis/security_solution/ip_overview.ts b/x-pack/test/api_integration/apis/security_solution/ip_overview.ts index 1dc0f6390ce7e9..6493c076179917 100644 --- a/x-pack/test/api_integration/apis/security_solution/ip_overview.ts +++ b/x-pack/test/api_integration/apis/security_solution/ip_overview.ts @@ -25,6 +25,7 @@ export default function ({ getService }: FtrProviderContext) { sourceId: 'default', ip: '151.205.0.17', defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }) @@ -52,6 +53,7 @@ export default function ({ getService }: FtrProviderContext) { sourceId: 'default', ip: '185.53.91.88', defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }) diff --git a/x-pack/test/api_integration/apis/security_solution/kpi_host_details.ts b/x-pack/test/api_integration/apis/security_solution/kpi_host_details.ts index 4b296078ff4438..c446fbb149e3a5 100644 --- a/x-pack/test/api_integration/apis/security_solution/kpi_host_details.ts +++ b/x-pack/test/api_integration/apis/security_solution/kpi_host_details.ts @@ -17,8 +17,8 @@ export default function ({ getService }: FtrProviderContext) { before(() => esArchiver.load('filebeat/default')); after(() => esArchiver.unload('filebeat/default')); - const FROM = new Date('2000-01-01T00:00:00.000Z').valueOf(); - const TO = new Date('3000-01-01T00:00:00.000Z').valueOf(); + const FROM = '2000-01-01T00:00:00.000Z'; + const TO = '3000-01-01T00:00:00.000Z'; const expectedResult = { __typename: 'KpiHostDetailsData', authSuccess: 0, @@ -86,6 +86,7 @@ export default function ({ getService }: FtrProviderContext) { }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], hostName: 'zeek-sensor-san-francisco', + docValueFields: [], inspect: false, }, }) @@ -167,6 +168,7 @@ export default function ({ getService }: FtrProviderContext) { from: FROM, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], hostName: 'zeek-sensor-san-francisco', inspect: false, }, diff --git a/x-pack/test/api_integration/apis/security_solution/kpi_hosts.ts b/x-pack/test/api_integration/apis/security_solution/kpi_hosts.ts index 30a0eac386c9df..dcea52edcddf97 100644 --- a/x-pack/test/api_integration/apis/security_solution/kpi_hosts.ts +++ b/x-pack/test/api_integration/apis/security_solution/kpi_hosts.ts @@ -17,8 +17,8 @@ export default function ({ getService }: FtrProviderContext) { before(() => esArchiver.load('filebeat/default')); after(() => esArchiver.unload('filebeat/default')); - const FROM = new Date('2000-01-01T00:00:00.000Z').valueOf(); - const TO = new Date('3000-01-01T00:00:00.000Z').valueOf(); + const FROM = '2000-01-01T00:00:00.000Z'; + const TO = '3000-01-01T00:00:00.000Z'; const expectedResult = { __typename: 'KpiHostsData', hosts: 1, @@ -108,6 +108,7 @@ export default function ({ getService }: FtrProviderContext) { from: FROM, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }) @@ -122,8 +123,8 @@ export default function ({ getService }: FtrProviderContext) { before(() => esArchiver.load('auditbeat/default')); after(() => esArchiver.unload('auditbeat/default')); - const FROM = new Date('2000-01-01T00:00:00.000Z').valueOf(); - const TO = new Date('3000-01-01T00:00:00.000Z').valueOf(); + const FROM = '2000-01-01T00:00:00.000Z'; + const TO = '3000-01-01T00:00:00.000Z'; const expectedResult = { __typename: 'KpiHostsData', hosts: 1, @@ -212,6 +213,7 @@ export default function ({ getService }: FtrProviderContext) { from: FROM, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }) diff --git a/x-pack/test/api_integration/apis/security_solution/kpi_network.ts b/x-pack/test/api_integration/apis/security_solution/kpi_network.ts index 6d6eee7d3468de..654607913d44af 100644 --- a/x-pack/test/api_integration/apis/security_solution/kpi_network.ts +++ b/x-pack/test/api_integration/apis/security_solution/kpi_network.ts @@ -17,8 +17,8 @@ export default function ({ getService }: FtrProviderContext) { before(() => esArchiver.load('filebeat/default')); after(() => esArchiver.unload('filebeat/default')); - const FROM = new Date('2000-01-01T00:00:00.000Z').valueOf(); - const TO = new Date('3000-01-01T00:00:00.000Z').valueOf(); + const FROM = '2000-01-01T00:00:00.000Z'; + const TO = '3000-01-01T00:00:00.000Z'; const expectedResult = { __typename: 'KpiNetworkData', networkEvents: 6158, @@ -85,6 +85,7 @@ export default function ({ getService }: FtrProviderContext) { from: FROM, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }) @@ -99,8 +100,8 @@ export default function ({ getService }: FtrProviderContext) { before(() => esArchiver.load('packetbeat/default')); after(() => esArchiver.unload('packetbeat/default')); - const FROM = new Date('2000-01-01T00:00:00.000Z').valueOf(); - const TO = new Date('3000-01-01T00:00:00.000Z').valueOf(); + const FROM = '2000-01-01T00:00:00.000Z'; + const TO = '3000-01-01T00:00:00.000Z'; const expectedResult = { __typename: 'KpiNetworkData', networkEvents: 6158, @@ -166,6 +167,7 @@ export default function ({ getService }: FtrProviderContext) { from: FROM, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }) diff --git a/x-pack/test/api_integration/apis/security_solution/network_dns.ts b/x-pack/test/api_integration/apis/security_solution/network_dns.ts index 9d88c7bc2389b2..e5f3ed18d32ea4 100644 --- a/x-pack/test/api_integration/apis/security_solution/network_dns.ts +++ b/x-pack/test/api_integration/apis/security_solution/network_dns.ts @@ -21,8 +21,8 @@ export default function ({ getService }: FtrProviderContext) { before(() => esArchiver.load('packetbeat/dns')); after(() => esArchiver.unload('packetbeat/dns')); - const FROM = new Date('2000-01-01T00:00:00.000Z').valueOf(); - const TO = new Date('3000-01-01T00:00:00.000Z').valueOf(); + const FROM = '2000-01-01T00:00:00.000Z'; + const TO = '3000-01-01T00:00:00.000Z'; it('Make sure that we get Dns data and sorting by uniqueDomains ascending', () => { return client @@ -30,6 +30,7 @@ export default function ({ getService }: FtrProviderContext) { query: networkDnsQuery, variables: { defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, isPtrIncluded: false, pagination: { @@ -65,6 +66,7 @@ export default function ({ getService }: FtrProviderContext) { query: networkDnsQuery, variables: { defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], isDnsHistogram: false, inspect: false, isPtrIncluded: false, diff --git a/x-pack/test/api_integration/apis/security_solution/network_top_n_flow.ts b/x-pack/test/api_integration/apis/security_solution/network_top_n_flow.ts index bbe934d840debe..6033fdfefa4db7 100644 --- a/x-pack/test/api_integration/apis/security_solution/network_top_n_flow.ts +++ b/x-pack/test/api_integration/apis/security_solution/network_top_n_flow.ts @@ -24,8 +24,8 @@ export default function ({ getService }: FtrProviderContext) { before(() => esArchiver.load('filebeat/default')); after(() => esArchiver.unload('filebeat/default')); - const FROM = new Date('2019-02-09T01:57:24.870Z').valueOf(); - const TO = new Date('2019-02-12T01:57:24.870Z').valueOf(); + const FROM = '2019-02-09T01:57:24.870Z'; + const TO = '2019-02-12T01:57:24.870Z'; it('Make sure that we get Source NetworkTopNFlow data with bytes_in descending sort', () => { return client @@ -47,6 +47,7 @@ export default function ({ getService }: FtrProviderContext) { querySize: 10, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }) @@ -84,6 +85,7 @@ export default function ({ getService }: FtrProviderContext) { querySize: 10, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }) @@ -121,6 +123,7 @@ export default function ({ getService }: FtrProviderContext) { querySize: 10, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }) @@ -155,6 +158,7 @@ export default function ({ getService }: FtrProviderContext) { querySize: 20, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }) diff --git a/x-pack/test/api_integration/apis/security_solution/overview_host.ts b/x-pack/test/api_integration/apis/security_solution/overview_host.ts index 1224fe3bd7dddb..ffbf9d89fc112e 100644 --- a/x-pack/test/api_integration/apis/security_solution/overview_host.ts +++ b/x-pack/test/api_integration/apis/security_solution/overview_host.ts @@ -19,8 +19,8 @@ export default function ({ getService }: FtrProviderContext) { before(() => esArchiver.load('auditbeat/overview')); after(() => esArchiver.unload('auditbeat/overview')); - const FROM = new Date('2000-01-01T00:00:00.000Z').valueOf(); - const TO = new Date('3000-01-01T00:00:00.000Z').valueOf(); + const FROM = '2000-01-01T00:00:00.000Z'; + const TO = '3000-01-01T00:00:00.000Z'; const expectedResult = { auditbeatAuditd: 2194, auditbeatFIM: 4, @@ -53,6 +53,7 @@ export default function ({ getService }: FtrProviderContext) { from: FROM, }, defaultIndex: DEFAULT_INDEX_PATTERN, + docValueFields: [], inspect: false, }, }) diff --git a/x-pack/test/api_integration/apis/security_solution/overview_network.ts b/x-pack/test/api_integration/apis/security_solution/overview_network.ts index b7f4184f2eeca1..6976b225a4d2ad 100644 --- a/x-pack/test/api_integration/apis/security_solution/overview_network.ts +++ b/x-pack/test/api_integration/apis/security_solution/overview_network.ts @@ -17,8 +17,8 @@ export default function ({ getService }: FtrProviderContext) { before(() => esArchiver.load('filebeat/default')); after(() => esArchiver.unload('filebeat/default')); - const FROM = new Date('2000-01-01T00:00:00.000Z').valueOf(); - const TO = new Date('3000-01-01T00:00:00.000Z').valueOf(); + const FROM = '2000-01-01T00:00:00.000Z'; + const TO = '3000-01-01T00:00:00.000Z'; const expectedResult = { auditbeatSocket: 0, @@ -45,6 +45,7 @@ export default function ({ getService }: FtrProviderContext) { from: FROM, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }) @@ -59,8 +60,8 @@ export default function ({ getService }: FtrProviderContext) { before(() => esArchiver.load('packetbeat/overview')); after(() => esArchiver.unload('packetbeat/overview')); - const FROM = new Date('2000-01-01T00:00:00.000Z').valueOf(); - const TO = new Date('3000-01-01T00:00:00.000Z').valueOf(); + const FROM = '2000-01-01T00:00:00.000Z'; + const TO = '3000-01-01T00:00:00.000Z'; const expectedResult = { auditbeatSocket: 0, filebeatCisco: 0, @@ -86,6 +87,7 @@ export default function ({ getService }: FtrProviderContext) { from: FROM, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }) @@ -100,8 +102,8 @@ export default function ({ getService }: FtrProviderContext) { before(() => esArchiver.load('auditbeat/overview')); after(() => esArchiver.unload('auditbeat/overview')); - const FROM = new Date('2000-01-01T00:00:00.000Z').valueOf(); - const TO = new Date('3000-01-01T00:00:00.000Z').valueOf(); + const FROM = '2000-01-01T00:00:00.000Z'; + const TO = '3000-01-01T00:00:00.000Z'; const expectedResult = { auditbeatSocket: 0, filebeatCisco: 0, @@ -127,6 +129,7 @@ export default function ({ getService }: FtrProviderContext) { from: FROM, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }) diff --git a/x-pack/test/api_integration/apis/security_solution/saved_objects/timeline.ts b/x-pack/test/api_integration/apis/security_solution/saved_objects/timeline.ts index 12e2378037c0a6..10ba9621c04305 100644 --- a/x-pack/test/api_integration/apis/security_solution/saved_objects/timeline.ts +++ b/x-pack/test/api_integration/apis/security_solution/saved_objects/timeline.ts @@ -137,7 +137,7 @@ export default function ({ getService }: FtrProviderContext) { }, }, title: 'some title', - dateRange: { start: 1560195800755, end: 1560282200756 }, + dateRange: { start: '2019-06-10T19:43:20.755Z', end: '2019-06-11T19:43:20.756Z' }, sort: { columnId: '@timestamp', sortDirection: 'desc' }, }; const response = await client.mutate({ diff --git a/x-pack/test/api_integration/apis/security_solution/sources.ts b/x-pack/test/api_integration/apis/security_solution/sources.ts index 7b4df5e23ca263..a9bbf09a9e6f96 100644 --- a/x-pack/test/api_integration/apis/security_solution/sources.ts +++ b/x-pack/test/api_integration/apis/security_solution/sources.ts @@ -25,6 +25,7 @@ export default function ({ getService }: FtrProviderContext) { variables: { sourceId: 'default', defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], }, }) .then((resp) => { diff --git a/x-pack/test/api_integration/apis/security_solution/timeline.ts b/x-pack/test/api_integration/apis/security_solution/timeline.ts index 9d4084a0e41b08..5bd015a130a5a4 100644 --- a/x-pack/test/api_integration/apis/security_solution/timeline.ts +++ b/x-pack/test/api_integration/apis/security_solution/timeline.ts @@ -13,8 +13,8 @@ import { } from '../../../../plugins/security_solution/public/graphql/types'; import { FtrProviderContext } from '../../ftr_provider_context'; -const LTE = new Date('3000-01-01T00:00:00.000Z').valueOf(); -const GTE = new Date('2000-01-01T00:00:00.000Z').valueOf(); +const TO = '3000-01-01T00:00:00.000Z'; +const FROM = '2000-01-01T00:00:00.000Z'; // typical values that have to change after an update from "scripts/es_archiver" const DATA_COUNT = 2; @@ -37,13 +37,13 @@ const FILTER_VALUE = { filter: [ { bool: { - should: [{ range: { '@timestamp': { gte: GTE } } }], + should: [{ range: { '@timestamp': { gte: FROM } } }], minimum_should_match: 1, }, }, { bool: { - should: [{ range: { '@timestamp': { lte: LTE } } }], + should: [{ range: { '@timestamp': { lte: TO } } }], minimum_should_match: 1, }, }, @@ -80,7 +80,13 @@ export default function ({ getService }: FtrProviderContext) { }, fieldRequested: ['@timestamp', 'host.name'], defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, + timerange: { + from: FROM, + to: TO, + interval: '12h', + }, }, }) .then((resp) => { @@ -110,7 +116,13 @@ export default function ({ getService }: FtrProviderContext) { }, fieldRequested: ['@timestamp', 'host.name'], defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, + timerange: { + from: FROM, + to: TO, + interval: '12h', + }, }, }) .then((resp) => { diff --git a/x-pack/test/api_integration/apis/security_solution/timeline_details.ts b/x-pack/test/api_integration/apis/security_solution/timeline_details.ts index 3524d7bf2db075..35f419fde894d6 100644 --- a/x-pack/test/api_integration/apis/security_solution/timeline_details.ts +++ b/x-pack/test/api_integration/apis/security_solution/timeline_details.ts @@ -314,6 +314,7 @@ export default function ({ getService }: FtrProviderContext) { indexName: INDEX_NAME, eventId: ID, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], }, }) .then((resp) => { diff --git a/x-pack/test/api_integration/apis/security_solution/tls.ts b/x-pack/test/api_integration/apis/security_solution/tls.ts index cbddcf6b0f9353..e5f6233d50d594 100644 --- a/x-pack/test/api_integration/apis/security_solution/tls.ts +++ b/x-pack/test/api_integration/apis/security_solution/tls.ts @@ -14,8 +14,8 @@ import { } from '../../../../plugins/security_solution/public/graphql/types'; import { FtrProviderContext } from '../../ftr_provider_context'; -const FROM = new Date('2000-01-01T00:00:00.000Z').valueOf(); -const TO = new Date('3000-01-01T00:00:00.000Z').valueOf(); +const FROM = '2000-01-01T00:00:00.000Z'; +const TO = '3000-01-01T00:00:00.000Z'; const SOURCE_IP = '10.128.0.35'; const DESTINATION_IP = '74.125.129.95'; @@ -117,6 +117,7 @@ export default function ({ getService }: FtrProviderContext) { querySize: 10, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }) @@ -149,6 +150,7 @@ export default function ({ getService }: FtrProviderContext) { querySize: 10, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }) @@ -186,6 +188,7 @@ export default function ({ getService }: FtrProviderContext) { querySize: 10, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }) @@ -217,6 +220,7 @@ export default function ({ getService }: FtrProviderContext) { querySize: 10, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }) diff --git a/x-pack/test/api_integration/apis/security_solution/uncommon_processes.ts b/x-pack/test/api_integration/apis/security_solution/uncommon_processes.ts index a08ba8d8a7cd15..f1e064bcc37bb3 100644 --- a/x-pack/test/api_integration/apis/security_solution/uncommon_processes.ts +++ b/x-pack/test/api_integration/apis/security_solution/uncommon_processes.ts @@ -10,8 +10,8 @@ import { uncommonProcessesQuery } from '../../../../plugins/security_solution/pu import { GetUncommonProcessesQuery } from '../../../../plugins/security_solution/public/graphql/types'; import { FtrProviderContext } from '../../ftr_provider_context'; -const FROM = new Date('2000-01-01T00:00:00.000Z').valueOf(); -const TO = new Date('3000-01-01T00:00:00.000Z').valueOf(); +const FROM = '2000-01-01T00:00:00.000Z'; +const TO = '3000-01-01T00:00:00.000Z'; // typical values that have to change after an update from "scripts/es_archiver" const TOTAL_COUNT = 3; @@ -45,6 +45,7 @@ export default function ({ getService }: FtrProviderContext) { querySize: 1, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }); @@ -72,6 +73,7 @@ export default function ({ getService }: FtrProviderContext) { querySize: 2, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }); @@ -99,6 +101,7 @@ export default function ({ getService }: FtrProviderContext) { querySize: 1, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }); @@ -126,6 +129,7 @@ export default function ({ getService }: FtrProviderContext) { querySize: 1, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], inspect: false, }, }); diff --git a/x-pack/test/api_integration/apis/security_solution/users.ts b/x-pack/test/api_integration/apis/security_solution/users.ts index eb7fba88a6a469..abb2c5b2f5bbdd 100644 --- a/x-pack/test/api_integration/apis/security_solution/users.ts +++ b/x-pack/test/api_integration/apis/security_solution/users.ts @@ -14,8 +14,8 @@ import { } from '../../../../plugins/security_solution/public/graphql/types'; import { FtrProviderContext } from '../../ftr_provider_context'; -const FROM = new Date('2000-01-01T00:00:00.000Z').valueOf(); -const TO = new Date('3000-01-01T00:00:00.000Z').valueOf(); +const FROM = '2000-01-01T00:00:00.000Z'; +const TO = '3000-01-01T00:00:00.000Z'; const IP = '0.0.0.0'; export default function ({ getService }: FtrProviderContext) { @@ -38,6 +38,7 @@ export default function ({ getService }: FtrProviderContext) { from: FROM, }, defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + docValueFields: [], ip: IP, flowTarget: FlowTarget.destination, sort: { field: UsersFields.name, direction: Direction.asc },