Added UI validation when creating a Webhook connector with invalid URL (#70025)
* Added UI validation when creating a Webhook connector with invalid URL * fixed tests * Fixed due to comments * fixed type check and extended error message for invalid URL * Fixed whitelisting of URL * fixed failing tests * fixed str
This commit is contained in:
parent
610bff1269
commit
438e905800
5 changed files with 63 additions and 2 deletions
|
@ -114,6 +114,17 @@ describe('config validation', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('config validation failed when a url is invalid', () => {
|
||||||
|
const config: Record<string, string> = {
|
||||||
|
url: 'example.com/do-something',
|
||||||
|
};
|
||||||
|
expect(() => {
|
||||||
|
validateConfig(actionType, config);
|
||||||
|
}).toThrowErrorMatchingInlineSnapshot(
|
||||||
|
'"error validating action type config: error configuring webhook action: unable to parse url: TypeError: Invalid URL: example.com/do-something"'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
test('config validation passes when valid headers are provided', () => {
|
test('config validation passes when valid headers are provided', () => {
|
||||||
// any for testing
|
// any for testing
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
|
|
@ -85,8 +85,20 @@ function validateActionTypeConfig(
|
||||||
configurationUtilities: ActionsConfigurationUtilities,
|
configurationUtilities: ActionsConfigurationUtilities,
|
||||||
configObject: ActionTypeConfigType
|
configObject: ActionTypeConfigType
|
||||||
) {
|
) {
|
||||||
|
let url: URL;
|
||||||
try {
|
try {
|
||||||
configurationUtilities.ensureWhitelistedUri(configObject.url);
|
url = new URL(configObject.url);
|
||||||
|
} catch (err) {
|
||||||
|
return i18n.translate('xpack.actions.builtin.webhook.webhookConfigurationErrorNoHostname', {
|
||||||
|
defaultMessage: 'error configuring webhook action: unable to parse url: {err}',
|
||||||
|
values: {
|
||||||
|
err,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
configurationUtilities.ensureWhitelistedUri(url.toString());
|
||||||
} catch (whitelistError) {
|
} catch (whitelistError) {
|
||||||
return i18n.translate('xpack.actions.builtin.webhook.webhookConfigurationError', {
|
return i18n.translate('xpack.actions.builtin.webhook.webhookConfigurationError', {
|
||||||
defaultMessage: 'error configuring webhook action: {message}',
|
defaultMessage: 'error configuring webhook action: {message}',
|
||||||
|
|
|
@ -40,7 +40,7 @@ describe('webhook connector validation', () => {
|
||||||
isPreconfigured: false,
|
isPreconfigured: false,
|
||||||
config: {
|
config: {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
url: 'http:\\test',
|
url: 'http://test.com',
|
||||||
headers: { 'content-type': 'text' },
|
headers: { 'content-type': 'text' },
|
||||||
},
|
},
|
||||||
} as WebhookActionConnector;
|
} as WebhookActionConnector;
|
||||||
|
@ -77,6 +77,31 @@ describe('webhook connector validation', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('connector validation fails when url in config is not valid', () => {
|
||||||
|
const actionConnector = {
|
||||||
|
secrets: {
|
||||||
|
user: 'user',
|
||||||
|
password: 'pass',
|
||||||
|
},
|
||||||
|
id: 'test',
|
||||||
|
actionTypeId: '.webhook',
|
||||||
|
name: 'webhook',
|
||||||
|
config: {
|
||||||
|
method: 'PUT',
|
||||||
|
url: 'invalid.url',
|
||||||
|
},
|
||||||
|
} as WebhookActionConnector;
|
||||||
|
|
||||||
|
expect(actionTypeModel.validateConnector(actionConnector)).toEqual({
|
||||||
|
errors: {
|
||||||
|
url: ['URL is invalid.'],
|
||||||
|
method: [],
|
||||||
|
user: [],
|
||||||
|
password: [],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('webhook action params validation', () => {
|
describe('webhook action params validation', () => {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { lazy } from 'react';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { ActionTypeModel, ValidationResult } from '../../../../types';
|
import { ActionTypeModel, ValidationResult } from '../../../../types';
|
||||||
import { WebhookActionParams, WebhookActionConnector } from '../types';
|
import { WebhookActionParams, WebhookActionConnector } from '../types';
|
||||||
|
import { isValidUrl } from '../../../lib/value_validators';
|
||||||
|
|
||||||
export function getActionType(): ActionTypeModel<WebhookActionConnector, WebhookActionParams> {
|
export function getActionType(): ActionTypeModel<WebhookActionConnector, WebhookActionParams> {
|
||||||
return {
|
return {
|
||||||
|
@ -43,6 +44,17 @@ export function getActionType(): ActionTypeModel<WebhookActionConnector, Webhook
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (action.config.url && !isValidUrl(action.config.url)) {
|
||||||
|
errors.url = [
|
||||||
|
...errors.url,
|
||||||
|
i18n.translate(
|
||||||
|
'xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.error.invalidUrlTextField',
|
||||||
|
{
|
||||||
|
defaultMessage: 'URL is invalid.',
|
||||||
|
}
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
if (!action.config.method) {
|
if (!action.config.method) {
|
||||||
errors.method.push(
|
errors.method.push(
|
||||||
i18n.translate(
|
i18n.translate(
|
||||||
|
|
|
@ -246,6 +246,7 @@ const WebhookActionConnectorFields: React.FunctionComponent<ActionConnectorField
|
||||||
isInvalid={errors.url.length > 0 && url !== undefined}
|
isInvalid={errors.url.length > 0 && url !== undefined}
|
||||||
fullWidth
|
fullWidth
|
||||||
value={url || ''}
|
value={url || ''}
|
||||||
|
placeholder="https://<site-url> or http://<site-url>"
|
||||||
data-test-subj="webhookUrlText"
|
data-test-subj="webhookUrlText"
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
editActionConfig('url', e.target.value);
|
editActionConfig('url', e.target.value);
|
||||||
|
|
Loading…
Reference in a new issue