mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
Convert timestamp before passing to validation (#192379)
Resolves: #186114 This PR adds a utility function to `stack_connectors` plugin to convert given date string or number (epoch) to proper type before passing to Date object or validation functions.
This commit is contained in:
parent
a27a044e8b
commit
48de1a57e7
4 changed files with 94 additions and 14 deletions
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { convertTimestamp } from './convert_timestamp';
|
||||
|
||||
describe('convert_timestamp', () => {
|
||||
const stringDate = '2024-09-06T11:10:24.681Z';
|
||||
const stringDateWithSlash = '2019/05/15';
|
||||
const stringDateWithDot = '10.12.1979';
|
||||
const anyString = 'asdfgh';
|
||||
const anyStringWithNumber = '123asdfghjkl';
|
||||
const epochDate = 1725880672;
|
||||
const stringifiedEpochDate = '1725880672';
|
||||
|
||||
it('should return a string date as it is', () => {
|
||||
expect(convertTimestamp(stringDate)).toBe(stringDate);
|
||||
});
|
||||
|
||||
it('should return any string as it is', () => {
|
||||
expect(convertTimestamp(anyString)).toBe(anyString);
|
||||
});
|
||||
|
||||
it('should return any string date with slash as it is', () => {
|
||||
expect(convertTimestamp(stringDateWithSlash)).toBe(stringDateWithSlash);
|
||||
});
|
||||
|
||||
it('should return any string date with dot as it is', () => {
|
||||
expect(convertTimestamp(stringDateWithDot)).toBe(stringDateWithDot);
|
||||
});
|
||||
|
||||
it('should return any string with some numbers in it as it is', () => {
|
||||
expect(convertTimestamp(anyStringWithNumber)).toBe(anyStringWithNumber);
|
||||
});
|
||||
|
||||
it('should return a number if the input is a stringified number', () => {
|
||||
expect(convertTimestamp('12345678')).toBe(12345678);
|
||||
});
|
||||
|
||||
it('should return an epoch date as it is', () => {
|
||||
expect(convertTimestamp(epochDate)).toBe(epochDate);
|
||||
});
|
||||
|
||||
it('should return a stringified epoch date as number', () => {
|
||||
expect(convertTimestamp(stringifiedEpochDate)).toBe(epochDate);
|
||||
});
|
||||
|
||||
it('should return null if timestamp is not passed', () => {
|
||||
expect(convertTimestamp()).toBe(null);
|
||||
});
|
||||
|
||||
it('should return null if timestamp is null', () => {
|
||||
expect(convertTimestamp(null)).toBe(null);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export function convertTimestamp(timestamp?: string | number | null): string | number | null {
|
||||
if (timestamp) {
|
||||
if (typeof timestamp === 'string') {
|
||||
const trimmedTimestamp = timestamp.trim();
|
||||
if (trimmedTimestamp.length > 0) {
|
||||
const parsedTimestamp = parseInt(trimmedTimestamp, 10);
|
||||
|
||||
if (!isNaN(parsedTimestamp) && JSON.stringify(parsedTimestamp) === trimmedTimestamp) {
|
||||
return parsedTimestamp; // return converted epoch
|
||||
}
|
||||
return trimmedTimestamp; // return string
|
||||
}
|
||||
}
|
||||
if (typeof timestamp === 'number') {
|
||||
return timestamp; // return epoch
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
|
@ -21,6 +21,7 @@ import {
|
|||
SecurityConnectorFeatureId,
|
||||
} from '@kbn/actions-plugin/common/types';
|
||||
import { postPagerduty } from './post_pagerduty';
|
||||
import { convertTimestamp } from '../lib/convert_timestamp';
|
||||
|
||||
// uses the PagerDuty Events API v2
|
||||
// https://v2.developer.pagerduty.com/docs/events-api-v2
|
||||
|
@ -99,19 +100,12 @@ export const ParamsSchema = schema.object(
|
|||
{ validate: validateParams }
|
||||
);
|
||||
|
||||
function validateTimestamp(timestamp?: string): string | null {
|
||||
if (timestamp) {
|
||||
return timestamp.trim().length > 0 ? timestamp.trim() : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function validateParams(paramsObject: unknown): string | void {
|
||||
const { timestamp, eventAction, dedupKey } = paramsObject as ActionParamsType;
|
||||
const validatedTimestamp = validateTimestamp(timestamp);
|
||||
if (validatedTimestamp != null) {
|
||||
const convertedTimestamp = convertTimestamp(timestamp);
|
||||
if (convertedTimestamp != null) {
|
||||
try {
|
||||
const date = moment(validatedTimestamp);
|
||||
const date = moment(convertedTimestamp);
|
||||
if (!date.isValid()) {
|
||||
return i18n.translate('xpack.stackConnectors.pagerduty.invalidTimestampErrorMessage', {
|
||||
defaultMessage: `error parsing timestamp "{timestamp}"`,
|
||||
|
@ -327,13 +321,13 @@ function getBodyForEventAction(actionId: string, params: ActionParamsType): Page
|
|||
return data;
|
||||
}
|
||||
|
||||
const validatedTimestamp = validateTimestamp(params.timestamp);
|
||||
const convertedTimestamp = convertTimestamp(params.timestamp);
|
||||
|
||||
data.payload = {
|
||||
summary: params.summary || 'No summary provided.',
|
||||
source: params.source || `Kibana Action ${actionId}`,
|
||||
severity: params.severity || 'info',
|
||||
...(validatedTimestamp ? { timestamp: moment(validatedTimestamp).toISOString() } : {}),
|
||||
...(convertedTimestamp ? { timestamp: moment(convertedTimestamp).toISOString() } : {}),
|
||||
...omitBy(pick(params, ['component', 'group', 'class']), isUndefined),
|
||||
...(params.customDetails ? { custom_details: params.customDetails } : {}),
|
||||
};
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { convertTimestamp } from '../lib/convert_timestamp';
|
||||
import { api as commonApi } from '../lib/servicenow/api';
|
||||
import {
|
||||
ExecutorSubActionAddEventParams,
|
||||
|
@ -15,8 +16,9 @@ import {
|
|||
const isValidDate = (d: Date) => !isNaN(d.valueOf());
|
||||
|
||||
const formatTimeOfEvent = (timeOfEvent: string | null): string | undefined => {
|
||||
if (timeOfEvent != null) {
|
||||
const date = new Date(timeOfEvent);
|
||||
const convertedTimestamp = convertTimestamp(timeOfEvent);
|
||||
if (convertedTimestamp != null) {
|
||||
const date = new Date(convertedTimestamp);
|
||||
|
||||
return isValidDate(date)
|
||||
? // The format is: yyyy-MM-dd HH:mm:ss GMT
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue