[Security solution] [Endpoint] Revisit blocklist wrong labels (#128773)

* Fixes wrong text for downgrade license docs link on blocklist.

* Fixes license downgraded banner for blocklist including the docs link

* Updates i18n keys for blocklist to be singular

* Removes unused param name

Co-authored-by: Ashokaditya <1849116+ashokaditya@users.noreply.github.com>
Co-authored-by: kevinlog <kevin.logan@elastic.co>
This commit is contained in:
David Sánchez 2022-04-13 00:03:25 +02:00 committed by GitHub
parent 7023ca6966
commit 935bac7b65
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 97 additions and 83 deletions

View file

@ -333,6 +333,7 @@ export const getDocLinks = ({ kibanaBranch }: GetDocLinkOptions): DocLinks => {
securitySolution: {
trustedApps: `${ELASTIC_WEBSITE_URL}guide/en/security/${DOC_LINK_VERSION}/trusted-apps-ov.html`,
eventFilters: `${ELASTIC_WEBSITE_URL}guide/en/security/${DOC_LINK_VERSION}/event-filters.html`,
blocklist: `${ELASTIC_WEBSITE_URL}guide/en/security/${DOC_LINK_VERSION}/blocklist.html`,
},
query: {
eql: `${ELASTICSEARCH_DOCS}eql.html`,

View file

@ -238,6 +238,7 @@ export interface DocLinks {
readonly securitySolution: {
readonly trustedApps: string;
readonly eventFilters: string;
readonly blocklist: string;
};
readonly query: {
readonly eql: string;

View file

@ -7,6 +7,7 @@
import React, { memo, useCallback, useEffect, useMemo, useState } from 'react';
import { i18n } from '@kbn/i18n';
import { DocLinks } from '@kbn/doc-links';
import { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types';
import {
EuiButton,
@ -20,6 +21,7 @@ import {
EuiFlyoutHeader,
EuiTitle,
} from '@elastic/eui';
import { EuiFlyoutSize } from '@elastic/eui/src/components/flyout/flyout';
import { HttpFetchError } from 'kibana/public';
import { useUrlParams } from '../../hooks/use_url_params';
@ -33,7 +35,7 @@ import {
} from '../types';
import { ManagementPageLoader } from '../../management_page_loader';
import { ExceptionsListApiClient } from '../../../services/exceptions_list/exceptions_list_api_client';
import { useToasts } from '../../../../common/lib/kibana';
import { useKibana, useToasts } from '../../../../common/lib/kibana';
import { createExceptionListItemForCreate } from '../../../../../common/endpoint/service/artifacts/utils';
import { useWithArtifactSubmitData } from '../hooks/use_with_artifact_submit_data';
import { useIsArtifactAllowedPerPolicyUsage } from '../hooks/use_is_artifact_allowed_per_policy_usage';
@ -96,7 +98,7 @@ export const ARTIFACT_FLYOUT_LABELS = Object.freeze({
* );
* }
*/
flyoutDowngradedLicenseDocsInfo: (): React.ReactNode =>
flyoutDowngradedLicenseDocsInfo: (_: DocLinks['securitySolution']): React.ReactNode =>
i18n.translate('xpack.securitySolution.artifactListPage.flyoutDowngradedLicenseDocsInfo', {
defaultMessage: 'For more information, see our documentation.',
}),
@ -188,6 +190,11 @@ export const ArtifactFlyout = memo<ArtifactFlyoutProps>(
'data-test-subj': dataTestSubj,
size = 'm',
}) => {
const {
docLinks: {
links: { securitySolution },
},
} = useKibana().services;
const getTestId = useTestIdGenerator(dataTestSubj);
const toasts = useToasts();
const isFlyoutOpened = useIsFlyoutOpened();
@ -364,7 +371,8 @@ export const ArtifactFlyout = memo<ArtifactFlyoutProps>(
iconType="help"
data-test-subj={getTestId('expiredLicenseCallout')}
>
{`${labels.flyoutDowngradedLicenseInfo} ${labels.flyoutDowngradedLicenseDocsInfo()}`}
{labels.flyoutDowngradedLicenseInfo}{' '}
{labels.flyoutDowngradedLicenseDocsInfo(securitySolution)}
</EuiCallOut>
)}

View file

@ -8,95 +8,95 @@
import { i18n } from '@kbn/i18n';
import { BlocklistConditionEntryField } from '@kbn/securitysolution-utils';
export const DETAILS_HEADER = i18n.translate('xpack.securitySolution.blocklists.details.header', {
export const DETAILS_HEADER = i18n.translate('xpack.securitySolution.blocklist.details.header', {
defaultMessage: 'Details',
});
export const DETAILS_HEADER_DESCRIPTION = i18n.translate(
'xpack.securitySolution.blocklists.details.header.description',
'xpack.securitySolution.blocklist.details.header.description',
{
defaultMessage:
'The blocklist prevents selected applications from running on your hosts by extending the list of processes the Endpoint considers malicious.',
}
);
export const NAME_LABEL = i18n.translate('xpack.securitySolution.blocklists.name.label', {
export const NAME_LABEL = i18n.translate('xpack.securitySolution.blocklist.name.label', {
defaultMessage: 'Name',
});
export const DESCRIPTION_LABEL = i18n.translate(
'xpack.securitySolution.blocklists.description.label',
'xpack.securitySolution.blocklist.description.label',
{
defaultMessage: 'Description',
}
);
export const CONDITIONS_HEADER = i18n.translate(
'xpack.securitySolution.blocklists.conditions.header',
'xpack.securitySolution.blocklist.conditions.header',
{
defaultMessage: 'Conditions',
}
);
export const CONDITIONS_HEADER_DESCRIPTION = i18n.translate(
'xpack.securitySolution.blocklists.conditions.header.description',
'xpack.securitySolution.blocklist.conditions.header.description',
{
defaultMessage:
'Select an operating system and add conditions. Availability of conditions may depend on your chosen OS.',
}
);
export const SELECT_OS_LABEL = i18n.translate('xpack.securitySolution.blocklists.os.label', {
export const SELECT_OS_LABEL = i18n.translate('xpack.securitySolution.blocklist.os.label', {
defaultMessage: 'Select operating system',
});
export const FIELD_LABEL = i18n.translate('xpack.securitySolution.blocklists.field.label', {
export const FIELD_LABEL = i18n.translate('xpack.securitySolution.blocklist.field.label', {
defaultMessage: 'Field',
});
export const OPERATOR_LABEL = i18n.translate('xpack.securitySolution.blocklists.operator.label', {
export const OPERATOR_LABEL = i18n.translate('xpack.securitySolution.blocklist.operator.label', {
defaultMessage: 'Operator',
});
export const VALUE_LABEL = i18n.translate('xpack.securitySolution.blocklists.value.label', {
export const VALUE_LABEL = i18n.translate('xpack.securitySolution.blocklist.value.label', {
defaultMessage: 'Value',
});
export const VALUE_LABEL_HELPER = i18n.translate(
'xpack.securitySolution.blocklists.value.label.helper',
'xpack.securitySolution.blocklist.value.label.helper',
{
defaultMessage: 'Type or copy & paste one or multiple comma delimited values',
}
);
export const CONDITION_FIELD_TITLE: { [K in BlocklistConditionEntryField]: string } = {
'file.hash.*': i18n.translate('xpack.securitySolution.blocklists.entry.field.hash', {
'file.hash.*': i18n.translate('xpack.securitySolution.blocklist.entry.field.hash', {
defaultMessage: 'Hash',
}),
'file.path': i18n.translate('xpack.securitySolution.blocklists.entry.field.path', {
'file.path': i18n.translate('xpack.securitySolution.blocklist.entry.field.path', {
defaultMessage: 'Path',
}),
'file.Ext.code_signature': i18n.translate(
'xpack.securitySolution.blocklists.entry.field.signature',
'xpack.securitySolution.blocklist.entry.field.signature',
{ defaultMessage: 'Signature' }
),
};
export const CONDITION_FIELD_DESCRIPTION: { [K in BlocklistConditionEntryField]: string } = {
'file.hash.*': i18n.translate('xpack.securitySolution.blocklists.entry.field.description.hash', {
'file.hash.*': i18n.translate('xpack.securitySolution.blocklist.entry.field.description.hash', {
defaultMessage: 'md5, sha1, or sha256',
}),
'file.path': i18n.translate('xpack.securitySolution.blocklists.entry.field.description.path', {
'file.path': i18n.translate('xpack.securitySolution.blocklist.entry.field.description.path', {
defaultMessage: 'The full path of the application',
}),
'file.Ext.code_signature': i18n.translate(
'xpack.securitySolution.blocklists.entry.field.description.signature',
'xpack.securitySolution.blocklist.entry.field.description.signature',
{ defaultMessage: 'The signer of the application' }
),
};
export const POLICY_SELECT_DESCRIPTION = i18n.translate(
'xpack.securitySolution.blocklists.policyAssignmentSectionDescription',
'xpack.securitySolution.blocklist.policyAssignmentSectionDescription',
{
defaultMessage:
'Assign this blocklist globally across all policies, or assign it to specific policies.',
@ -104,26 +104,32 @@ export const POLICY_SELECT_DESCRIPTION = i18n.translate(
);
export const ERRORS = {
NAME_REQUIRED: i18n.translate('xpack.securitySolution.blocklists.errors.name.required', {
NAME_REQUIRED: i18n.translate('xpack.securitySolution.blocklist.errors.name.required', {
defaultMessage: 'Name is required',
}),
VALUE_REQUIRED: i18n.translate('xpack.securitySolution.blocklists.errors.values.required', {
VALUE_REQUIRED: i18n.translate('xpack.securitySolution.blocklist.errors.values.required', {
defaultMessage: 'Field entry must have a value',
}),
INVALID_HASH: i18n.translate('xpack.securitySolution.blocklists.errors.values.invalidHash', {
INVALID_HASH: i18n.translate('xpack.securitySolution.blocklist.errors.values.invalidHash', {
defaultMessage: 'Invalid hash value',
}),
INVALID_PATH: i18n.translate('xpack.securitySolution.blocklists.warnings.values.invalidPath', {
INVALID_PATH: i18n.translate('xpack.securitySolution.blocklist.warnings.values.invalidPath', {
defaultMessage: 'Path may be formed incorrectly; verify value',
}),
WILDCARD_PRESENT: i18n.translate(
'xpack.securitySolution.blocklist.warnings.values.wildcardPresent',
{
defaultMessage: "A wildcard in the filename will affect the endpoint's performance",
}
),
DUPLICATE_VALUE: i18n.translate(
'xpack.securitySolution.blocklists.warnings.values.duplicateValue',
'xpack.securitySolution.blocklist.warnings.values.duplicateValue',
{
defaultMessage: 'This value already exists',
}
),
DUPLICATE_VALUES: i18n.translate(
'xpack.securitySolution.blocklists.warnings.values.duplicateValues',
'xpack.securitySolution.blocklist.warnings.values.duplicateValues',
{
defaultMessage: 'One or more duplicate values removed',
}

View file

@ -7,6 +7,9 @@
import React, { memo } from 'react';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { DocLinks } from '@kbn/doc-links';
import { EuiLink } from '@elastic/eui';
import { useHttp } from '../../../../common/lib/kibana';
import { ArtifactListPage, ArtifactListPageProps } from '../../../components/artifact_list_page';
@ -48,7 +51,7 @@ const BLOCKLIST_PAGE_LABELS: ArtifactListPageProps['labels'] = {
),
flyoutCreateSubmitSuccess: ({ name }) =>
i18n.translate('xpack.securitySolution.blocklist.flyoutCreateSubmitSuccess', {
defaultMessage: '"{name}" has been added to your blocklist.', // FIXME: match this to design (needs count of items)
defaultMessage: '"{name}" has been added to your blocklist.',
values: { name },
}),
flyoutEditSubmitSuccess: ({ name }) =>
@ -56,28 +59,23 @@ const BLOCKLIST_PAGE_LABELS: ArtifactListPageProps['labels'] = {
defaultMessage: '"{name}" has been updated.',
values: { name },
}),
flyoutDowngradedLicenseDocsInfo: () => {
return 'tbd...';
// FIXME: define docs link for license downgrade message. sample code below
// const { docLinks } = useKibana().services;
// return (
// <FormattedMessage
// id="some-id-1"
// defaultMessage="For more information, see our {link}."
// value={{
// link: (
// <EuiLink target="_blank" href={`${docLinks.links.securitySolution.eventFilters}`}>
// {' '}
// <FormattedMessage
// id="dome-id-2"
// defaultMessage="Event filters documentation"
// />{' '}
// </EuiLink>
// ),
// }}
// />
// );
flyoutDowngradedLicenseDocsInfo: (
securitySolutionDocsLinks: DocLinks['securitySolution']
): React.ReactNode => {
return (
<>
<FormattedMessage
id="xpack.securitySolution.blocklist.flyoutDowngradedLicenseDocsInfo"
defaultMessage="For more information, see our "
/>
<EuiLink target="_blank" href={`${securitySolutionDocsLinks.blocklist}`}>
<FormattedMessage
id="xpack.securitySolution.blocklist.flyoutDowngradedLicenseDocsLink"
defaultMessage="Blocklist documentation"
/>
</EuiLink>
</>
);
},
deleteActionSuccess: (itemName) =>
i18n.translate('xpack.securitySolution.blocklist.deleteSuccess', {
@ -85,15 +83,15 @@ const BLOCKLIST_PAGE_LABELS: ArtifactListPageProps['labels'] = {
values: { itemName },
}),
emptyStateTitle: i18n.translate('xpack.securitySolution.blocklist.emptyStateTitle', {
defaultMessage: 'Add your first blocklist',
defaultMessage: 'Add your first blocklist entry',
}),
emptyStateInfo: i18n.translate('xpack.securitySolution.blocklist.emptyStateInfo', {
defaultMessage:
'The blocklist prevents selected applications from running on your hosts by extending the list of processes the Endpoint considers malicious.',
}),
emptyStateInfo: i18n.translate(
'xpack.securitySolution.blocklist.emptyStateInfo',
{ defaultMessage: 'Add a blocklist to prevent execution on the endpoint' } // FIXME: need wording here form PM
),
emptyStatePrimaryButtonLabel: i18n.translate(
'xpack.securitySolution.blocklist.emptyStatePrimaryButtonLabel',
{ defaultMessage: 'Add blocklist' }
{ defaultMessage: 'Add blocklist entry' }
),
searchPlaceholderInfo: i18n.translate('xpack.securitySolution.blocklist.searchPlaceholderInfo', {
defaultMessage: 'Search on the fields below: name, description, value',

View file

@ -87,7 +87,7 @@ export const BLOCKLISTS_LABELS = {
),
cardTitle: (
<FormattedMessage
id="xpack.securitySolution.endpoint.blocklists.fleetIntegration.title"
id="xpack.securitySolution.endpoint.blocklist.fleetIntegration.title"
defaultMessage="Blocklist"
/>
),

View file

@ -50,7 +50,7 @@ export const BLOCKLISTS_LABELS = {
}),
cardTitle: (
<FormattedMessage
id="xpack.securitySolution.endpoint.blocklists.fleetIntegration.title"
id="xpack.securitySolution.endpoint.blocklist.fleetIntegration.title"
defaultMessage="Blocklist"
/>
),

View file

@ -10,27 +10,27 @@ import { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'
export const POLICY_ARTIFACT_BLOCKLISTS_LABELS = Object.freeze({
deleteModalTitle: i18n.translate(
'xpack.securitySolution.endpoint.policy.blocklists.list.removeDialog.title',
'xpack.securitySolution.endpoint.policy.blocklist.list.removeDialog.title',
{
defaultMessage: 'Remove blocklist entry from policy',
}
),
deleteModalImpactInfo: i18n.translate(
'xpack.securitySolution.endpoint.policy.blocklists.list.removeDialog.messageCallout',
'xpack.securitySolution.endpoint.policy.blocklist.list.removeDialog.messageCallout',
{
defaultMessage:
'This blocklist entry will be removed only from this policy and can still be found and managed from the artifact page.',
}
),
deleteModalErrorMessage: i18n.translate(
'xpack.securitySolution.endpoint.policy.blocklists.list.removeDialog.errorToastTitle',
'xpack.securitySolution.endpoint.policy.blocklist.list.removeDialog.errorToastTitle',
{
defaultMessage: 'Error while attempting to remove blocklist entry',
}
),
flyoutWarningCalloutMessage: (maxNumber: number) =>
i18n.translate(
'xpack.securitySolution.endpoint.policy.blocklists.layout.flyout.searchWarning.text',
'xpack.securitySolution.endpoint.policy.blocklist.layout.flyout.searchWarning.text',
{
defaultMessage:
'Only the first {maxNumber} blocklist entries are displayed. Please use the search bar to refine the results.',
@ -38,30 +38,30 @@ export const POLICY_ARTIFACT_BLOCKLISTS_LABELS = Object.freeze({
}
),
flyoutNoArtifactsToBeAssignedMessage: i18n.translate(
'xpack.securitySolution.endpoint.policy.blocklists.layout.flyout.noAssignable',
'xpack.securitySolution.endpoint.policy.blocklist.layout.flyout.noAssignable',
{
defaultMessage: 'There are no blocklist entries that can be assigned to this policy.',
}
),
flyoutTitle: i18n.translate(
'xpack.securitySolution.endpoint.policy.blocklists.layout.flyout.title',
'xpack.securitySolution.endpoint.policy.blocklist.layout.flyout.title',
{
defaultMessage: 'Assign blocklist entries',
}
),
flyoutSubtitle: (policyName: string): string =>
i18n.translate('xpack.securitySolution.endpoint.policy.blocklists.layout.flyout.subtitle', {
i18n.translate('xpack.securitySolution.endpoint.policy.blocklist.layout.flyout.subtitle', {
defaultMessage: 'Select blocklist entries to add to {policyName}',
values: { policyName },
}),
flyoutSearchPlaceholder: i18n.translate(
'xpack.securitySolution.endpoint.policy.blocklists.layout.search.label',
'xpack.securitySolution.endpoint.policy.blocklist.layout.search.label',
{
defaultMessage: 'Search blocklist entries',
}
),
flyoutErrorMessage: i18n.translate(
'xpack.securitySolution.endpoint.policy.blocklists.layout.flyout.toastError.text',
'xpack.securitySolution.endpoint.policy.blocklist.layout.flyout.toastError.text',
{
defaultMessage: `An error occurred updating blocklist entry`,
}
@ -69,53 +69,53 @@ export const POLICY_ARTIFACT_BLOCKLISTS_LABELS = Object.freeze({
flyoutSuccessMessageText: (updatedExceptions: ExceptionListItemSchema[]): string =>
updatedExceptions.length > 1
? i18n.translate(
'xpack.securitySolution.endpoint.policy.blocklists.layout.flyout.toastSuccess.textMultiples',
'xpack.securitySolution.endpoint.policy.blocklist.layout.flyout.toastSuccess.textMultiples',
{
defaultMessage: '{count} blocklist entries have been added to your list.',
values: { count: updatedExceptions.length },
}
)
: i18n.translate(
'xpack.securitySolution.endpoint.policy.blocklists.layout.flyout.toastSuccess.textSingle',
'xpack.securitySolution.endpoint.policy.blocklist.layout.flyout.toastSuccess.textSingle',
{
defaultMessage: '"{name}" blocklist has been added to your list.',
values: { name: updatedExceptions[0].name },
}
),
emptyUnassignedTitle: i18n.translate(
'xpack.securitySolution.endpoint.policy.blocklists.empty.unassigned.title',
'xpack.securitySolution.endpoint.policy.blocklist.empty.unassigned.title',
{ defaultMessage: 'No assigned blocklist entries' }
),
emptyUnassignedMessage: (policyName: string): string =>
i18n.translate('xpack.securitySolution.endpoint.policy.blocklists.empty.unassigned.content', {
i18n.translate('xpack.securitySolution.endpoint.policy.blocklist.empty.unassigned.content', {
defaultMessage:
'There are currently no blocklist entries assigned to {policyName}. Assign blocklist entries now or add and manage them on the blocklist page.',
values: { policyName },
}),
emptyUnassignedPrimaryActionButtonTitle: i18n.translate(
'xpack.securitySolution.endpoint.policy.blocklists.empty.unassigned.primaryAction',
'xpack.securitySolution.endpoint.policy.blocklist.empty.unassigned.primaryAction',
{
defaultMessage: 'Assign blocklist entry',
}
),
emptyUnassignedSecondaryActionButtonTitle: i18n.translate(
'xpack.securitySolution.endpoint.policy.blocklists.empty.unassigned.secondaryAction',
'xpack.securitySolution.endpoint.policy.blocklist.empty.unassigned.secondaryAction',
{
defaultMessage: 'Manage blocklist entries',
}
),
emptyUnexistingTitle: i18n.translate(
'xpack.securitySolution.endpoint.policy.blocklists.empty.unexisting.title',
{ defaultMessage: 'No blocklist entries exist' }
'xpack.securitySolution.endpoint.policy.blocklist.empty.unexisting.title',
{ defaultMessage: 'No blocklists entries exist' }
),
emptyUnexistingMessage: i18n.translate(
'xpack.securitySolution.endpoint.policy.blocklists.empty.unexisting.content',
'xpack.securitySolution.endpoint.policy.blocklist.empty.unexisting.content',
{
defaultMessage: 'There are currently no blocklist entries applied to your endpoints.',
}
),
emptyUnexistingPrimaryActionButtonTitle: i18n.translate(
'xpack.securitySolution.endpoint.policy.blocklists.empty.unexisting.action',
'xpack.securitySolution.endpoint.policy.blocklist.empty.unexisting.action',
{ defaultMessage: 'Add blocklist entry' }
),
listTotalItemCountMessage: (totalItemsCount: number): string =>
@ -125,28 +125,28 @@ export const POLICY_ARTIFACT_BLOCKLISTS_LABELS = Object.freeze({
values: { totalItemsCount },
}),
listRemoveActionNotAllowedMessage: i18n.translate(
'xpack.securitySolution.endpoint.policy.blocklists.list.removeActionNotAllowed',
'xpack.securitySolution.endpoint.policy.blocklist.list.removeActionNotAllowed',
{
defaultMessage: 'Globally applied blocklist cannot be removed from policy.',
}
),
listSearchPlaceholderMessage: i18n.translate(
'xpack.securitySolution.endpoint.policy.blocklists.list.search.placeholder',
'xpack.securitySolution.endpoint.policy.blocklist.list.search.placeholder',
{
defaultMessage: `Search on the fields below: name, description, value`,
}
),
layoutTitle: i18n.translate('xpack.securitySolution.endpoint.policy.blocklists.layout.title', {
layoutTitle: i18n.translate('xpack.securitySolution.endpoint.policy.blocklist.layout.title', {
defaultMessage: 'Assigned blocklist entries',
}),
layoutAssignButtonTitle: i18n.translate(
'xpack.securitySolution.endpoint.policy.blocklists.layout.assignToPolicy',
'xpack.securitySolution.endpoint.policy.blocklist.layout.assignToPolicy',
{
defaultMessage: 'Assign blocklist entry to policy',
}
),
layoutViewAllLinkMessage: i18n.translate(
'xpack.securitySolution.endpoint.policy.blocklists.layout.about.viewAllLinkLabel',
'xpack.securitySolution.endpoint.policy.blocklist.layout.about.viewAllLinkLabel',
{
defaultMessage: 'view all blocklist entries',
}

View file

@ -155,7 +155,7 @@ export const PolicyTabs = React.memo(() => {
...POLICY_ARTIFACT_BLOCKLISTS_LABELS,
layoutAboutMessage: (count: number, link: React.ReactElement): React.ReactNode => (
<FormattedMessage
id="xpack.securitySolution.endpoint.policy.blocklists.list.about"
id="xpack.securitySolution.endpoint.policy.blocklist.list.about"
defaultMessage="There {count, plural, one {is} other {are}} {count} {count, plural, =1 {blocklist} other {blocklist entries}} associated with this policy. Click here to {link}"
values={{ count, link }}
/>