mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Security Solution][Admin][Event Filters] Wildcard warning with IS operator for event filters creation/editing (#178440)
## Summary - [x] Adds updated warning messaging for trusted apps entries that use wildcards `*?` with the "IS" operator - [x] Three different warnings: callout, individual entry item warnings and a final confirmation modal when the user tries to add an event filter with ineffective IS / wildcard combination entry. - [x] Unit tests - [x] Fixes bug in endpoint exceptions where there is a missing tooltip icon for the wildcard performance warning # Screenshots   Bug Fix 
This commit is contained in:
parent
0cbf527f08
commit
47c7174bff
14 changed files with 186 additions and 56 deletions
|
@ -39,6 +39,7 @@ const BOOLEAN_OPTIONS = [
|
|||
];
|
||||
|
||||
const SINGLE_SELECTION = { asPlainText: true };
|
||||
type Warning = string | React.ReactNode;
|
||||
|
||||
interface AutocompleteFieldMatchProps {
|
||||
placeholder: string;
|
||||
|
@ -54,6 +55,8 @@ interface AutocompleteFieldMatchProps {
|
|||
autocompleteService: AutocompleteStart;
|
||||
onChange: (arg: string) => void;
|
||||
onError?: (arg: boolean) => void;
|
||||
onWarning?: (arg: boolean) => void;
|
||||
warning?: Warning;
|
||||
'aria-label'?: string;
|
||||
}
|
||||
|
||||
|
@ -71,6 +74,8 @@ export const AutocompleteFieldMatchComponent: React.FC<AutocompleteFieldMatchPro
|
|||
autocompleteService,
|
||||
onChange,
|
||||
onError,
|
||||
onWarning,
|
||||
warning,
|
||||
'aria-label': ariaLabel,
|
||||
}): JSX.Element => {
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
|
@ -122,6 +127,15 @@ export const AutocompleteFieldMatchComponent: React.FC<AutocompleteFieldMatchPro
|
|||
[setError, onError]
|
||||
);
|
||||
|
||||
const handleWarning = useCallback(
|
||||
(warn: Warning | undefined): void => {
|
||||
if (onWarning) {
|
||||
onWarning(warn !== undefined);
|
||||
}
|
||||
},
|
||||
[onWarning]
|
||||
);
|
||||
|
||||
const { comboOptions, labels, selectedComboOptions } = useMemo(
|
||||
(): GetGenericComboBoxPropsReturn =>
|
||||
getGenericComboBoxProps<string>({
|
||||
|
@ -148,18 +162,20 @@ export const AutocompleteFieldMatchComponent: React.FC<AutocompleteFieldMatchPro
|
|||
if (searchVal !== '' && selectedField != null) {
|
||||
const err = paramIsValid(searchVal, selectedField, isRequired, touched);
|
||||
handleError(err);
|
||||
handleWarning(warning);
|
||||
|
||||
if (!err) handleSpacesWarning(searchVal);
|
||||
setSearchQuery(searchVal);
|
||||
}
|
||||
},
|
||||
[handleError, handleSpacesWarning, isRequired, selectedField, touched]
|
||||
[handleError, handleSpacesWarning, isRequired, selectedField, touched, handleWarning, warning]
|
||||
);
|
||||
|
||||
const handleCreateOption = useCallback(
|
||||
(option: string): boolean | undefined => {
|
||||
const err = paramIsValid(option, selectedField, isRequired, touched);
|
||||
handleError(err);
|
||||
handleWarning(warning);
|
||||
|
||||
if (err != null) {
|
||||
// Explicitly reject the user's input
|
||||
|
@ -171,7 +187,16 @@ export const AutocompleteFieldMatchComponent: React.FC<AutocompleteFieldMatchPro
|
|||
onChange(option);
|
||||
return undefined;
|
||||
},
|
||||
[isRequired, onChange, selectedField, touched, handleError, handleSpacesWarning]
|
||||
[
|
||||
isRequired,
|
||||
onChange,
|
||||
selectedField,
|
||||
touched,
|
||||
handleError,
|
||||
handleSpacesWarning,
|
||||
handleWarning,
|
||||
warning,
|
||||
]
|
||||
);
|
||||
|
||||
const handleNonComboBoxInputChange = useCallback(
|
||||
|
@ -194,7 +219,8 @@ export const AutocompleteFieldMatchComponent: React.FC<AutocompleteFieldMatchPro
|
|||
|
||||
const err = paramIsValid(selectedValue, selectedField, isRequired, true);
|
||||
handleError(err);
|
||||
}, [setIsTouched, handleError, selectedValue, selectedField, isRequired]);
|
||||
handleWarning(warning);
|
||||
}, [setIsTouched, handleError, selectedValue, selectedField, isRequired, warning, handleWarning]);
|
||||
|
||||
const inputPlaceholder = useMemo((): string => {
|
||||
if (isLoading || isLoadingSuggestions) {
|
||||
|
@ -229,7 +255,7 @@ export const AutocompleteFieldMatchComponent: React.FC<AutocompleteFieldMatchPro
|
|||
isInvalid={selectedField != null && error != null}
|
||||
data-test-subj="valuesAutocompleteMatchLabel"
|
||||
fullWidth
|
||||
helpText={showSpacesWarning && i18n.FIELD_SPACE_WARNING}
|
||||
helpText={warning || (showSpacesWarning && i18n.FIELD_SPACE_WARNING)}
|
||||
>
|
||||
<EuiComboBox
|
||||
placeholder={inputPlaceholder}
|
||||
|
@ -268,6 +294,7 @@ export const AutocompleteFieldMatchComponent: React.FC<AutocompleteFieldMatchPro
|
|||
handleSearchChange,
|
||||
handleCreateOption,
|
||||
setIsTouchedValue,
|
||||
warning,
|
||||
fieldInputWidth,
|
||||
ariaLabel,
|
||||
]);
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
hasSimpleExecutableName,
|
||||
OperatingSystem,
|
||||
ConditionEntryField,
|
||||
hasWildcardAndInvalidOperator,
|
||||
validateHasWildcardWithWrongOperator,
|
||||
validatePotentialWildcardInput,
|
||||
validateFilePathInput,
|
||||
validateWildcardInput,
|
||||
|
@ -131,16 +131,24 @@ describe('validateFilePathInput', () => {
|
|||
|
||||
describe('Wildcard and invalid operator', () => {
|
||||
it('should return TRUE when operator is not "WILDCARD" and value contains a wildcard', () => {
|
||||
expect(hasWildcardAndInvalidOperator({ operator: 'match', value: 'asdf*' })).toEqual(true);
|
||||
expect(validateHasWildcardWithWrongOperator({ operator: 'match', value: 'asdf*' })).toEqual(
|
||||
true
|
||||
);
|
||||
});
|
||||
it('should return FALSE when operator is not "WILDCARD" and value does not contain a wildcard', () => {
|
||||
expect(hasWildcardAndInvalidOperator({ operator: 'match', value: 'asdf' })).toEqual(false);
|
||||
expect(validateHasWildcardWithWrongOperator({ operator: 'match', value: 'asdf' })).toEqual(
|
||||
false
|
||||
);
|
||||
});
|
||||
it('should return FALSE when operator is "WILDCARD" and value contains a wildcard', () => {
|
||||
expect(hasWildcardAndInvalidOperator({ operator: 'wildcard', value: 'asdf*' })).toEqual(false);
|
||||
expect(validateHasWildcardWithWrongOperator({ operator: 'wildcard', value: 'asdf*' })).toEqual(
|
||||
false
|
||||
);
|
||||
});
|
||||
it('should return FALSE when operator is "WILDCARD" and value does not contain a wildcard', () => {
|
||||
expect(hasWildcardAndInvalidOperator({ operator: 'wildcard', value: 'asdf' })).toEqual(false);
|
||||
expect(validateHasWildcardWithWrongOperator({ operator: 'wildcard', value: 'asdf' })).toEqual(
|
||||
false
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ export enum OperatingSystem {
|
|||
|
||||
export type EntryTypes = 'match' | 'wildcard' | 'match_any';
|
||||
export type TrustedAppEntryTypes = Extract<EntryTypes, 'match' | 'wildcard'>;
|
||||
export type EventFiltersTypes = EntryTypes | 'exists' | 'nested';
|
||||
|
||||
export const validatePotentialWildcardInput = ({
|
||||
field = '',
|
||||
|
@ -106,11 +107,11 @@ export const validateWildcardInput = (value?: string): string | undefined => {
|
|||
}
|
||||
};
|
||||
|
||||
export const hasWildcardAndInvalidOperator = ({
|
||||
export const validateHasWildcardWithWrongOperator = ({
|
||||
operator,
|
||||
value,
|
||||
}: {
|
||||
operator: EntryTypes | TrustedAppEntryTypes;
|
||||
operator: TrustedAppEntryTypes | EventFiltersTypes;
|
||||
value: string;
|
||||
}): boolean => {
|
||||
if (operator !== 'wildcard' && validateWildcardInput(value)) {
|
||||
|
|
|
@ -15,6 +15,7 @@ import {
|
|||
EuiIcon,
|
||||
EuiIconTip,
|
||||
EuiSpacer,
|
||||
EuiText,
|
||||
useEuiPaddingSize,
|
||||
} from '@elastic/eui';
|
||||
import styled from 'styled-components';
|
||||
|
@ -374,8 +375,21 @@ export const BuilderEntryItem: React.FC<EntryItemProps> = ({
|
|||
}
|
||||
};
|
||||
|
||||
// show warning when a wildcard is detected with the IS operator
|
||||
const getWildcardWithIsOperatorWarning = (): React.ReactNode => {
|
||||
return (
|
||||
<EuiText size="xs">
|
||||
<FormattedMessage
|
||||
id="xpack.lists.exceptions.builder.exceptionIsOperator.warningMessage.incorrectWildCardUsage"
|
||||
defaultMessage="Change the operator to 'matches' to ensure wildcards run properly."
|
||||
/>{' '}
|
||||
<EuiIconTip type="iInCircle" content={i18n.WILDCARD_WITH_IS_OPERATOR_TOOLTIP} />
|
||||
</EuiText>
|
||||
);
|
||||
};
|
||||
|
||||
// show this when wildcard with matches operator
|
||||
const getEventFilterWildcardWarningInfo = (precedingWarning: string): React.ReactNode => {
|
||||
const getWildcardPerformanceWarningInfo = (precedingWarning: string): React.ReactNode => {
|
||||
return (
|
||||
<p>
|
||||
{precedingWarning}{' '}
|
||||
|
@ -404,6 +418,9 @@ export const BuilderEntryItem: React.FC<EntryItemProps> = ({
|
|||
switch (type) {
|
||||
case OperatorTypeEnum.MATCH:
|
||||
const value = typeof entry.value === 'string' ? entry.value : undefined;
|
||||
const fieldMatchWarning = /[*?]/.test(value ?? '')
|
||||
? getWildcardWithIsOperatorWarning()
|
||||
: '';
|
||||
return (
|
||||
<AutocompleteFieldMatchComponent
|
||||
autocompleteService={autocompleteService}
|
||||
|
@ -416,6 +433,8 @@ export const BuilderEntryItem: React.FC<EntryItemProps> = ({
|
|||
isClearable={false}
|
||||
indexPattern={indexPattern}
|
||||
onError={handleError}
|
||||
onWarning={handleWarning}
|
||||
warning={fieldMatchWarning}
|
||||
onChange={handleFieldMatchValueChange}
|
||||
isRequired
|
||||
data-test-subj="exceptionBuilderEntryFieldMatch"
|
||||
|
@ -460,9 +479,7 @@ export const BuilderEntryItem: React.FC<EntryItemProps> = ({
|
|||
value: wildcardValue,
|
||||
});
|
||||
actualWarning =
|
||||
warning === WILDCARD_WARNING && listType === 'endpoint_events'
|
||||
? getEventFilterWildcardWarningInfo(warning)
|
||||
: warning;
|
||||
warning === WILDCARD_WARNING ? getWildcardPerformanceWarningInfo(warning) : warning;
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -107,3 +107,11 @@ export const CONFLICT_MULTIPLE_INDEX_DESCRIPTION = (name: string, count: number)
|
|||
defaultMessage: '{name} ({count} indices)',
|
||||
values: { count, name },
|
||||
});
|
||||
|
||||
export const WILDCARD_WITH_IS_OPERATOR_TOOLTIP = i18n.translate(
|
||||
'xpack.lists.exceptions.builder.exceptionIsOperator.warningmessage.tooltip',
|
||||
{
|
||||
defaultMessage:
|
||||
'Using a wildcard with the "IS" operator can make an entry ineffective. Change the operator to "MATCHES" to ensure wildcards run properly.',
|
||||
}
|
||||
);
|
||||
|
|
|
@ -193,3 +193,25 @@ export const CONSOLE_COMMANDS = {
|
|||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const CONFIRM_WARNING_MODAL_LABELS = {
|
||||
title: i18n.translate('xpack.securitySolution.artifacts.confirmWarningModal.title', {
|
||||
defaultMessage: 'Confirm trusted application',
|
||||
}),
|
||||
body: i18n.translate('xpack.securitySolution.artifacts.confirmWarningModal.body', {
|
||||
defaultMessage:
|
||||
'Using a "*" or a "?" in the value with the "IS" operator can make the entry ineffective. Change the operator to ‘matches’ to ensure wildcards run properly. Select “cancel” to revise your entry, or "add" to continue with the entry in its current state.',
|
||||
}),
|
||||
confirmButton: i18n.translate(
|
||||
'xpack.securitySolution.artifacts.confirmWarningModal.confirmButtonText',
|
||||
{
|
||||
defaultMessage: 'Add',
|
||||
}
|
||||
),
|
||||
cancelButton: i18n.translate(
|
||||
'xpack.securitySolution.trustedapps.confirmWarningModal.cancelButtonText',
|
||||
{
|
||||
defaultMessage: 'Cancel',
|
||||
}
|
||||
),
|
||||
};
|
||||
|
|
|
@ -28,7 +28,9 @@ import { useWithArtifactSubmitData } from '../../../../components/artifact_list_
|
|||
import type {
|
||||
ArtifactFormComponentOnChangeCallbackProps,
|
||||
ArtifactFormComponentProps,
|
||||
ArtifactConfirmModalLabelProps,
|
||||
} from '../../../../components/artifact_list_page/types';
|
||||
import { ArtifactConfirmModal } from '../../../../components/artifact_list_page/components/artifact_confirm_modal';
|
||||
import { EventFiltersForm } from './form';
|
||||
|
||||
import { getInitialExceptionFromEvent } from '../utils';
|
||||
|
@ -72,6 +74,12 @@ export const EventFiltersFlyout: React.FC<EventFiltersFlyoutProps> = memo(
|
|||
getInitialExceptionFromEvent(data)
|
||||
);
|
||||
|
||||
const [confirmModalLabels, setConfirmModalLabels] = useState<
|
||||
ArtifactConfirmModalLabelProps | undefined
|
||||
>();
|
||||
|
||||
const [showConfirmModal, setShowConfirmModal] = useState<boolean>(false);
|
||||
|
||||
const policiesIsLoading = useMemo<boolean>(
|
||||
() => policiesRequest.isLoading || policiesRequest.isRefetching,
|
||||
[policiesRequest]
|
||||
|
@ -121,7 +129,7 @@ export const EventFiltersFlyout: React.FC<EventFiltersFlyoutProps> = memo(
|
|||
onClose();
|
||||
}, [isSubmittingData, policiesIsLoading, onClose]);
|
||||
|
||||
const handleOnSubmit = useCallback(() => {
|
||||
const submitEventFilter = useCallback(() => {
|
||||
return submitData(exception, {
|
||||
onSuccess: (result) => {
|
||||
toasts.addSuccess(getCreationSuccessMessage(result));
|
||||
|
@ -133,6 +141,14 @@ export const EventFiltersFlyout: React.FC<EventFiltersFlyoutProps> = memo(
|
|||
});
|
||||
}, [exception, onClose, submitData, toasts]);
|
||||
|
||||
const handleOnSubmit = useCallback(() => {
|
||||
if (confirmModalLabels) {
|
||||
setShowConfirmModal(true);
|
||||
} else {
|
||||
return submitEventFilter();
|
||||
}
|
||||
}, [confirmModalLabels, submitEventFilter]);
|
||||
|
||||
const confirmButtonMemo = useMemo(
|
||||
() => (
|
||||
<EuiButton
|
||||
|
@ -165,8 +181,26 @@ export const EventFiltersFlyout: React.FC<EventFiltersFlyoutProps> = memo(
|
|||
if (!formState) return;
|
||||
setIsFormValid(formState.isValid);
|
||||
setException(formState.item);
|
||||
setConfirmModalLabels(formState.confirmModalLabels);
|
||||
}, []);
|
||||
|
||||
const confirmModal = useMemo(() => {
|
||||
if (confirmModalLabels) {
|
||||
const { title, body, confirmButton, cancelButton } = confirmModalLabels;
|
||||
return (
|
||||
<ArtifactConfirmModal
|
||||
title={title}
|
||||
body={body}
|
||||
confirmButton={confirmButton}
|
||||
cancelButton={cancelButton}
|
||||
onSuccess={submitEventFilter}
|
||||
onCancel={() => setShowConfirmModal(false)}
|
||||
data-test-subj="artifactConfirmModal"
|
||||
/>
|
||||
);
|
||||
}
|
||||
}, [confirmModalLabels, submitEventFilter]);
|
||||
|
||||
return (
|
||||
<EuiFlyout
|
||||
size="l"
|
||||
|
@ -230,6 +264,7 @@ export const EventFiltersFlyout: React.FC<EventFiltersFlyoutProps> = memo(
|
|||
<EuiFlexItem grow={false}>{confirmButtonMemo}</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlyoutFooter>
|
||||
{showConfirmModal && confirmModal}
|
||||
</EuiFlyout>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -474,6 +474,31 @@ describe('Event filter form', () => {
|
|||
rerender();
|
||||
expect(renderResult.findByTestId('duplicate-fields-warning-message')).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should not show warning callout when wildcard is used with the "MATCHES" operator', async () => {
|
||||
formProps.item.entries = [
|
||||
{
|
||||
field: 'event.category',
|
||||
operator: 'included',
|
||||
type: 'wildcard',
|
||||
value: 'valuewithwildcard*',
|
||||
},
|
||||
];
|
||||
rerender();
|
||||
expect(renderResult.queryByTestId('wildcardWithWrongOperatorCallout')).toBeNull();
|
||||
});
|
||||
it('should show warning callout when wildcard is used with the "IS" operator', async () => {
|
||||
formProps.item.entries = [
|
||||
{
|
||||
field: 'event.category',
|
||||
operator: 'included',
|
||||
type: 'match',
|
||||
value: 'valuewithwildcard*',
|
||||
},
|
||||
];
|
||||
rerender();
|
||||
await expect(renderResult.findByTestId('wildcardWithWrongOperatorCallout')).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Errors', () => {
|
||||
|
|
|
@ -23,7 +23,8 @@ import { FormattedMessage } from '@kbn/i18n-react';
|
|||
|
||||
import type { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types';
|
||||
import { EVENT_FILTERS_OPERATORS } from '@kbn/securitysolution-list-utils';
|
||||
import { OperatingSystem } from '@kbn/securitysolution-utils';
|
||||
import { WildCardWithWrongOperatorCallout } from '@kbn/securitysolution-exception-list-components';
|
||||
import { OperatingSystem, validateHasWildcardWithWrongOperator } from '@kbn/securitysolution-utils';
|
||||
|
||||
import { getExceptionBuilderComponentLazy } from '@kbn/lists-plugin/public';
|
||||
import type { OnChangeProps } from '@kbn/lists-plugin/public';
|
||||
|
@ -55,7 +56,7 @@ import {
|
|||
OS_LABEL,
|
||||
RULE_NAME,
|
||||
} from '../event_filters_list';
|
||||
import { OS_TITLES } from '../../../../common/translations';
|
||||
import { OS_TITLES, CONFIRM_WARNING_MODAL_LABELS } from '../../../../common/translations';
|
||||
import { ENDPOINT_EVENT_FILTERS_LIST_ID, EVENT_FILTER_LIST_TYPE } from '../../constants';
|
||||
|
||||
import type { EffectedPolicySelection } from '../../../../components/effected_policy_select';
|
||||
|
@ -143,8 +144,9 @@ export const EventFiltersForm: React.FC<ArtifactFormComponentProps & { allowSele
|
|||
[exception]
|
||||
);
|
||||
const [wasByPolicy, setWasByPolicy] = useState(!isGlobalPolicyEffected(exception?.tags));
|
||||
|
||||
const [hasDuplicateFields, setHasDuplicateFields] = useState<boolean>(false);
|
||||
const [hasWildcardWithWrongOperator, setHasWildcardWithWrongOperator] =
|
||||
useState<boolean>(false);
|
||||
// This value has to be memoized to avoid infinite useEffect loop on useFetchIndex
|
||||
const indexNames = useMemo(() => [eventsIndexPattern], []);
|
||||
const [isIndexPatternLoading, { indexPatterns }] = useFetchIndex(
|
||||
|
@ -193,9 +195,12 @@ export const EventFiltersForm: React.FC<ArtifactFormComponentProps & { allowSele
|
|||
onChange({
|
||||
item,
|
||||
isValid: isFormValid && areConditionsValid,
|
||||
confirmModalLabels: hasWildcardWithWrongOperator
|
||||
? CONFIRM_WARNING_MODAL_LABELS
|
||||
: undefined,
|
||||
});
|
||||
},
|
||||
[areConditionsValid, exception, isFormValid, onChange]
|
||||
[areConditionsValid, exception, isFormValid, onChange, hasWildcardWithWrongOperator]
|
||||
);
|
||||
|
||||
// set initial state of `wasByPolicy` that checks
|
||||
|
@ -413,6 +418,19 @@ export const EventFiltersForm: React.FC<ArtifactFormComponentProps & { allowSele
|
|||
if (!hasFormChanged) setHasFormChanged(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// handle wildcard with wrong operator case
|
||||
arg.exceptionItems[0]?.entries.forEach((e) => {
|
||||
if (
|
||||
validateHasWildcardWithWrongOperator({
|
||||
operator: (e as EventFilterItemEntries[number]).type,
|
||||
value: (e as EventFilterItemEntries[number]).value,
|
||||
})
|
||||
) {
|
||||
setHasWildcardWithWrongOperator(true);
|
||||
}
|
||||
});
|
||||
|
||||
const updatedItem: Partial<ArtifactFormComponentProps['item']> =
|
||||
arg.exceptionItems[0] !== undefined
|
||||
? {
|
||||
|
@ -563,13 +581,14 @@ export const EventFiltersForm: React.FC<ArtifactFormComponentProps & { allowSele
|
|||
{detailsSection}
|
||||
<EuiHorizontalRule />
|
||||
{criteriaSection}
|
||||
{hasWildcardWithWrongOperator && <WildCardWithWrongOperatorCallout />}
|
||||
{hasDuplicateFields && (
|
||||
<>
|
||||
<EuiSpacer size="xs" />
|
||||
<EuiText color="subdued" size="xs" data-test-subj="duplicate-fields-warning-message">
|
||||
<FormattedMessage
|
||||
id="xpack.securitySolution.eventFilters.warningMessage.duplicateFields"
|
||||
defaultMessage="Using multiples of the same filed values can degrade Endpoint performance and/or create ineffective rules"
|
||||
defaultMessage="Using multiples of the same field values can degrade Endpoint performance and/or create ineffective rules"
|
||||
/>
|
||||
</EuiText>
|
||||
</>
|
||||
|
|
|
@ -22,7 +22,7 @@ import {
|
|||
import type { AllConditionEntryFields, EntryTypes } from '@kbn/securitysolution-utils';
|
||||
import {
|
||||
hasSimpleExecutableName,
|
||||
hasWildcardAndInvalidOperator,
|
||||
validateHasWildcardWithWrongOperator,
|
||||
isPathValid,
|
||||
ConditionEntryField,
|
||||
OperatingSystem,
|
||||
|
@ -58,9 +58,8 @@ import {
|
|||
NAME_LABEL,
|
||||
POLICY_SELECT_DESCRIPTION,
|
||||
SELECT_OS_LABEL,
|
||||
CONFIRM_WARNING_MODAL_LABELS,
|
||||
} from '../translations';
|
||||
import { OS_TITLES } from '../../../../common/translations';
|
||||
import { OS_TITLES, CONFIRM_WARNING_MODAL_LABELS } from '../../../../common/translations';
|
||||
import type { LogicalConditionBuilderProps } from './logical_condition';
|
||||
import { LogicalConditionBuilder } from './logical_condition';
|
||||
import { useTestIdGenerator } from '../../../../hooks/use_test_id_generator';
|
||||
|
@ -166,7 +165,7 @@ const validateValues = (values: ArtifactFormComponentProps['item']): ValidationR
|
|||
});
|
||||
|
||||
if (
|
||||
hasWildcardAndInvalidOperator({
|
||||
validateHasWildcardWithWrongOperator({
|
||||
operator: entry.type as EntryTypes,
|
||||
value: (entry as TrustedAppConditionEntry).value,
|
||||
})
|
||||
|
|
|
@ -165,25 +165,3 @@ export const INPUT_ERRORS = {
|
|||
values: { row: index + 1 },
|
||||
}),
|
||||
};
|
||||
|
||||
export const CONFIRM_WARNING_MODAL_LABELS = {
|
||||
title: i18n.translate('xpack.securitySolution.trustedapps.confirmWarningModal.title', {
|
||||
defaultMessage: 'Confirm trusted application',
|
||||
}),
|
||||
body: i18n.translate('xpack.securitySolution.trustedapps.confirmWarningModal.body', {
|
||||
defaultMessage:
|
||||
'Using a "*" or a "?" in the value and with the "IS" operator can make the entry ineffective. Change the operator to ‘matches’ to ensure wildcards run properly. Select “cancel” to revise your entry, or "add" to continue with entry in its current state.',
|
||||
}),
|
||||
confirmButton: i18n.translate(
|
||||
'xpack.securitySolution.trustedapps.confirmWarningModal.confirmButtonText',
|
||||
{
|
||||
defaultMessage: 'Add',
|
||||
}
|
||||
),
|
||||
cancelButton: i18n.translate(
|
||||
'xpack.securitySolution.trustedapps.confirmWarningModal.cancelButtonText',
|
||||
{
|
||||
defaultMessage: 'Cancel',
|
||||
}
|
||||
),
|
||||
};
|
||||
|
|
|
@ -38122,10 +38122,7 @@
|
|||
"xpack.securitySolution.trustedApps.cardActionEditLabel": "Modifier une application de confiance",
|
||||
"xpack.securitySolution.trustedApps.conditions.header": "Conditions",
|
||||
"xpack.securitySolution.trustedApps.conditions.header.description": "Sélectionnez un système d'exploitation et ajoutez des conditions. La disponibilité des conditions peut dépendre de votre système d'exploitation.",
|
||||
"xpack.securitySolution.trustedapps.confirmWarningModal.body": "L'utilisation de \"*\" ou de \"?\" dans la valeur avec l'opérateur \"IS\" peut rendre l'entrée inefficace. Remplacez l'opérateur par \"matches\" (correspondances) pour que les caractères génériques soient correctement exécutés. Sélectionnez \"annuler\" pour modifier votre entrée, ou \"ajouter\" pour continuer avec l'entrée dans son état actuel.",
|
||||
"xpack.securitySolution.trustedapps.confirmWarningModal.cancelButtonText": "Annuler",
|
||||
"xpack.securitySolution.trustedapps.confirmWarningModal.confirmButtonText": "Ajouter",
|
||||
"xpack.securitySolution.trustedapps.confirmWarningModal.title": "Confirmer qu'il s'agit d'une application de confiance",
|
||||
"xpack.securitySolution.trustedapps.create.conditionRequiredMsg": "Au moins une définition de champ est requise",
|
||||
"xpack.securitySolution.trustedapps.create.description": "Description",
|
||||
"xpack.securitySolution.trustedapps.create.nameRequiredMsg": "Le nom est obligatoire",
|
||||
|
|
|
@ -38091,10 +38091,7 @@
|
|||
"xpack.securitySolution.trustedApps.cardActionEditLabel": "信頼できるアプリケーションを編集",
|
||||
"xpack.securitySolution.trustedApps.conditions.header": "条件",
|
||||
"xpack.securitySolution.trustedApps.conditions.header.description": "オペレーティングシステムを選択して、条件を追加します。条件の可用性は選択したOSによって異なる場合があります。",
|
||||
"xpack.securitySolution.trustedapps.confirmWarningModal.body": "値で*または?を使用して、IS演算子と結合すると、エントリが無効になる場合があります。演算子を「一致」に変更すると、ワイルドカードが確実に正常に動作します。エントリを修正するには、[キャンセル]を選択します。現在の状態でエントリを続行するには、[追加]を選択します。",
|
||||
"xpack.securitySolution.trustedapps.confirmWarningModal.cancelButtonText": "キャンセル",
|
||||
"xpack.securitySolution.trustedapps.confirmWarningModal.confirmButtonText": "追加",
|
||||
"xpack.securitySolution.trustedapps.confirmWarningModal.title": "信頼できるアプリケーションを確認",
|
||||
"xpack.securitySolution.trustedapps.create.conditionRequiredMsg": "1つ以上のフィールド定義が必要です",
|
||||
"xpack.securitySolution.trustedapps.create.description": "説明",
|
||||
"xpack.securitySolution.trustedapps.create.nameRequiredMsg": "名前が必要です",
|
||||
|
|
|
@ -38134,10 +38134,7 @@
|
|||
"xpack.securitySolution.trustedApps.cardActionEditLabel": "编辑受信任的应用程序",
|
||||
"xpack.securitySolution.trustedApps.conditions.header": "条件",
|
||||
"xpack.securitySolution.trustedApps.conditions.header.description": "选择操作系统,然后添加条件。条件的可用性可能取决于您选定的 OS。",
|
||||
"xpack.securitySolution.trustedapps.confirmWarningModal.body": "在带“IS”运算符的值中使用“*”或“?”可使该条目失效。将运算符更改为“matches”可确保通配符正常运行。选择“取消”可修正您的条目,或选择“添加”以继续处理处于其当前状态的条目。",
|
||||
"xpack.securitySolution.trustedapps.confirmWarningModal.cancelButtonText": "取消",
|
||||
"xpack.securitySolution.trustedapps.confirmWarningModal.confirmButtonText": "添加",
|
||||
"xpack.securitySolution.trustedapps.confirmWarningModal.title": "确认受信任的应用程序",
|
||||
"xpack.securitySolution.trustedapps.create.conditionRequiredMsg": "至少需要一个字段定义",
|
||||
"xpack.securitySolution.trustedapps.create.description": "描述",
|
||||
"xpack.securitySolution.trustedapps.create.nameRequiredMsg": "“名称”必填",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue