mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 10:40:07 -04:00
[Security Solution] Move threat intelligence to security solution (#214369)
# Summary This PR merges Threat Intelligence plugin with security solution, in order to remove duplicated and unnecessary code introduced as a bridge between the TI plugin and Security Solution + to simpify maintenance. No new functionality is implemented here, other than changing imports and some dependendies to use security solution code directly, without weird bridges or hacks / indirections. ## Testing Navigate to threat intelligence plugin / indicators and try clicking around. It is hard to list every feature we have there but in general it should work without errors. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
6033441a2f
commit
af0b369627
279 changed files with 3138 additions and 2636 deletions
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
|
@ -1066,7 +1066,6 @@ x-pack/solutions/security/plugins/security_solution @elastic/security-solution
|
|||
x-pack/solutions/security/plugins/security_solution_ess @elastic/security-solution
|
||||
x-pack/solutions/security/plugins/security_solution_serverless @elastic/security-solution
|
||||
x-pack/solutions/security/plugins/session_view @elastic/kibana-cloud-security-posture
|
||||
x-pack/solutions/security/plugins/threat_intelligence @elastic/security-threat-hunting-investigations
|
||||
x-pack/test
|
||||
x-pack/test_serverless
|
||||
x-pack/test/alerting_api_integration/common/plugins/aad @elastic/response-ops
|
||||
|
|
|
@ -225,7 +225,6 @@ mapped_pages:
|
|||
| [taskManager](https://github.com/elastic/kibana/blob/main/x-pack/platform/plugins/shared/task_manager/README.md) | The task manager is a generic system for running background tasks. |
|
||||
| [taskManagerDependencies](https://github.com/elastic/kibana/blob/main/x-pack/platform/plugins/private/task_manager_dependencies/README.md) | This plugin is used as a temporary sidecar plugin to enable the task manager plugin access to the encrypted saved objects client as there is a circular dependency if the task manager were to require the encrypted saved objects plugin directly. |
|
||||
| [telemetryCollectionXpack](https://github.com/elastic/kibana/blob/main/x-pack/platform/plugins/private/telemetry_collection_xpack/README.md) | Gathers all usage collection, retrieving them from both: OSS and X-Pack plugins. |
|
||||
| [threatIntelligence](https://github.com/elastic/kibana/blob/main/x-pack/solutions/security/plugins/threat_intelligence/README.md) | Elastic Threat Intelligence makes it easy to analyze and investigate potential security threats by aggregating data from multiple sources in one place. You’ll be able to view data from all activated threat intelligence feeds and take action. |
|
||||
| [timelines](https://github.com/elastic/kibana/blob/main/x-pack/platform/plugins/shared/timelines/README.md) | Timelines is a plugin that provides a grid component with accompanying server side apis to help users identify events of interest and perform root cause analysis within Kibana. |
|
||||
| [transform](https://github.com/elastic/kibana/blob/main/x-pack/platform/plugins/private/transform/README.md) | This plugin provides access to the transforms features provided by Elasticsearch. It follows Kibana's standard plugin architecture, originally the plugin boilerplate code was taken from the snapshot/restore plugin. |
|
||||
| [translations](translations-plugin.md) | Contains Elastic-supported translations. Owned by the Localizations team. For adding localizations and instrument a ui to support translated content, see https://github.com/elastic/kibana/tree/main/src/platform/packages/shared/kbn-i18n |
|
||||
|
|
|
@ -981,7 +981,6 @@
|
|||
"@kbn/testing-embedded-lens-plugin": "link:x-pack/examples/testing_embedded_lens",
|
||||
"@kbn/third-party-lens-navigation-prompt-plugin": "link:x-pack/examples/third_party_lens_navigation_prompt",
|
||||
"@kbn/third-party-vis-lens-example-plugin": "link:x-pack/examples/third_party_vis_lens_example",
|
||||
"@kbn/threat-intelligence-plugin": "link:x-pack/solutions/security/plugins/threat_intelligence",
|
||||
"@kbn/timelines-plugin": "link:x-pack/platform/plugins/shared/timelines",
|
||||
"@kbn/timelion-grammar": "link:src/platform/packages/private/kbn-timelion-grammar",
|
||||
"@kbn/timerange": "link:src/platform/packages/shared/kbn-timerange",
|
||||
|
|
|
@ -164,7 +164,6 @@ pageLoadAssetSize:
|
|||
synthetics: 55971
|
||||
telemetry: 51957
|
||||
telemetryManagementSection: 38586
|
||||
threatIntelligence: 44299
|
||||
timelines: 327300
|
||||
transform: 41007
|
||||
triggersActionsUi: 135613
|
||||
|
|
|
@ -61,7 +61,6 @@ export const storybookAliases = {
|
|||
// security_solution_packages: 'x-pack/solutions/security/packages/storybook/config',
|
||||
serverless: 'src/platform/packages/shared/serverless/storybook/config',
|
||||
shared_ux: 'src/platform/packages/private/shared-ux/storybook/config',
|
||||
threat_intelligence: 'x-pack/solutions/security/plugins/threat_intelligence/.storybook',
|
||||
triggers_actions_ui: 'x-pack/platform/plugins/shared/triggers_actions_ui/.storybook',
|
||||
ui_actions_enhanced: 'src/platform/plugins/shared/ui_actions_enhanced/.storybook',
|
||||
unified_search: 'src/platform/plugins/shared/unified_search/.storybook',
|
||||
|
|
|
@ -2008,8 +2008,6 @@
|
|||
"@kbn/third-party-lens-navigation-prompt-plugin/*": ["x-pack/examples/third_party_lens_navigation_prompt/*"],
|
||||
"@kbn/third-party-vis-lens-example-plugin": ["x-pack/examples/third_party_vis_lens_example"],
|
||||
"@kbn/third-party-vis-lens-example-plugin/*": ["x-pack/examples/third_party_vis_lens_example/*"],
|
||||
"@kbn/threat-intelligence-plugin": ["x-pack/solutions/security/plugins/threat_intelligence"],
|
||||
"@kbn/threat-intelligence-plugin/*": ["x-pack/solutions/security/plugins/threat_intelligence/*"],
|
||||
"@kbn/timelines-plugin": ["x-pack/platform/plugins/shared/timelines"],
|
||||
"@kbn/timelines-plugin/*": ["x-pack/platform/plugins/shared/timelines/*"],
|
||||
"@kbn/timelion-grammar": ["src/platform/packages/private/kbn-timelion-grammar"],
|
||||
|
|
|
@ -46123,68 +46123,68 @@
|
|||
"xpack.synthetics.windowValueExpression.numberOfChecksPopoverTitleLabel": "Nombre de vérifications",
|
||||
"xpack.synthetics.windowValueExpression.numberOfLocPopoverTitleLabel": "Nombre d'emplacements",
|
||||
"xpack.synthetics.windowValueExpression.percentLabel": "{numberOfLocations} {numberOfLocations, plural, one {emplacement} other {emplacements}}",
|
||||
"xpack.threatIntelligence.addToBlockList": "Ajouter une entrée dans la liste noire",
|
||||
"xpack.threatIntelligence.addToExistingCase": "Ajouter à un cas existant",
|
||||
"xpack.threatIntelligence.addToNewCase": "Ajouter au nouveau cas",
|
||||
"xpack.threatIntelligence.blocklist.flyoutTitle": "Ajouter une liste noire",
|
||||
"xpack.threatIntelligence.cases.eventDescription": "ajouté un indicateur de compromis",
|
||||
"xpack.threatIntelligence.cases.indicatorFeedName": "Nom du fil :",
|
||||
"xpack.threatIntelligence.cases.indicatorName": "Nom de l'indicateur :",
|
||||
"xpack.threatIntelligence.cases.indicatorType": "Type d'indicateur :",
|
||||
"xpack.threatIntelligence.common.emptyPage.body1": "Elastic Threat Intelligence facilite l'analyse et l'investigation des menaces potentielles pour la sécurité en regroupant les données de plusieurs sources en un seul endroit.",
|
||||
"xpack.threatIntelligence.common.emptyPage.body2": "Vous pourrez consulter les données de tous les flux Threat Intelligence activés et prendre des mesures à partir de cette page.",
|
||||
"xpack.threatIntelligence.common.emptyPage.body3": "Pour vous lancer avec Elastic Threat Intelligence, activez une ou plusieurs intégrations Threat Intelligence depuis la page Intégrations ou bien ingérez des données avec Filebeat. Pour plus d'informations, consultez la ressource {docsLink}.",
|
||||
"xpack.threatIntelligence.common.emptyPage.buttonText": "Ajouter des intégrations",
|
||||
"xpack.threatIntelligence.common.emptyPage.docsLinkText": "Sécurité de la documentation",
|
||||
"xpack.threatIntelligence.common.emptyPage.imgAlt": "Activer les intégrations Threat Intelligence",
|
||||
"xpack.threatIntelligence.common.emptyPage.title": "Prise en main d’Elastic Threat Intelligence",
|
||||
"xpack.threatIntelligence.empty.description": "Essayer de rechercher sur une période plus longue ou de modifier votre recherche",
|
||||
"xpack.threatIntelligence.empty.title": "Aucun résultat ne correspond à vos critères de recherche.",
|
||||
"xpack.threatIntelligence.field.@timestamp": "@timestamp",
|
||||
"xpack.threatIntelligence.field.threat.feed.name": "Fil",
|
||||
"xpack.threatIntelligence.field.threat.indicator.confidence": "Confiance",
|
||||
"xpack.threatIntelligence.field.threat.indicator.first_seen": "Vu en premier",
|
||||
"xpack.threatIntelligence.field.threat.indicator.last_seen": "Vu en dernier",
|
||||
"xpack.threatIntelligence.field.threat.indicator.marking.tlp": "Marquage TLP",
|
||||
"xpack.threatIntelligence.field.threat.indicator.name": "Indicateur",
|
||||
"xpack.threatIntelligence.field.threat.indicator.type": "Type d’indicateur",
|
||||
"xpack.threatIntelligence.indicator.barChart.popover": "Plus d'actions",
|
||||
"xpack.threatIntelligence.indicator.barchartSection.title": "Tendance",
|
||||
"xpack.threatIntelligence.indicator.fieldSelector.label": "Empiler par",
|
||||
"xpack.threatIntelligence.indicator.fieldsTable.fieldColumnLabel": "Champ",
|
||||
"xpack.threatIntelligence.indicator.fieldsTable.valueColumnLabel": "Valeur",
|
||||
"xpack.threatIntelligence.indicator.flyout.jsonTabLabel": "JSON",
|
||||
"xpack.threatIntelligence.indicator.flyout.overviewTabLabel": "Aperçu",
|
||||
"xpack.threatIntelligence.indicator.flyout.panelSubTitle": "Vu en premier :",
|
||||
"xpack.threatIntelligence.indicator.flyout.panelTitleWithOverviewTab": "Détails de l'indicateur",
|
||||
"xpack.threatIntelligence.indicator.flyout.tableTabLabel": "Tableau",
|
||||
"xpack.threatIntelligence.indicator.flyoutOverviewTable.highlightedFields": "Champs en surbrillance",
|
||||
"xpack.threatIntelligence.indicator.flyoutOverviewTable.viewAllFieldsInTable": "Afficher tous les champs dans le tableau",
|
||||
"xpack.threatIntelligence.indicator.flyoutTable.errorMessageBody": "Une erreur s'est produite lors de l'affichage des champs et des valeurs des indicateurs.",
|
||||
"xpack.threatIntelligence.indicator.flyoutTable.errorMessageTitle": "Impossible d'afficher les informations des indicateurs",
|
||||
"xpack.threatIntelligence.indicator.table.actionColumnLabel": "Actions",
|
||||
"xpack.threatIntelligence.indicator.table.moreActions": "Plus d'actions",
|
||||
"xpack.threatIntelligence.indicator.table.viewDetailsButton": "Afficher les détails",
|
||||
"xpack.threatIntelligence.indicatorNameFieldDescription": "Nom d'affichage de l'indicateur généré pendant le temps d'exécution",
|
||||
"xpack.threatIntelligence.indicators.flyout.take-action.button": "Entreprendre une action",
|
||||
"xpack.threatIntelligence.indicators.table.copyToClipboardLabel": "Copier dans le presse-papiers",
|
||||
"xpack.threatIntelligence.inspectorFlyoutTitle": "Requêtes de recherche des indicateurs",
|
||||
"xpack.threatIntelligence.inspectTitle": "Inspecter",
|
||||
"xpack.threatIntelligence.investigateInTimelineButton": "Investiguer dans la chronologie",
|
||||
"xpack.threatIntelligence.more-actions.popover": "Plus d'actions",
|
||||
"xpack.threatIntelligence.navigation.indicatorsNavItemDescription": "Elastic Threat Intelligence vous aide à voir si vous êtes exposé ou avez été exposé à des menaces connues actuelles ou passées.",
|
||||
"xpack.threatIntelligence.navigation.indicatorsNavItemKeywords": "Indicateurs",
|
||||
"xpack.threatIntelligence.navigation.indicatorsNavItemLabel": "Indicateurs",
|
||||
"xpack.threatIntelligence.navigation.intelligenceNavItemLabel": "Intelligence",
|
||||
"xpack.threatIntelligence.paywall.body": "Démarrez un essai gratuit ou mettez à niveau votre licence vers Enterprise pour utiliser la Threat Intelligence.",
|
||||
"xpack.threatIntelligence.paywall.title": "Toujours plus avec Security !",
|
||||
"xpack.threatIntelligence.paywall.trial": "Démarrer un essai gratuit",
|
||||
"xpack.threatIntelligence.paywall.upgrade": "Mettre à niveau",
|
||||
"xpack.threatIntelligence.queryBar.filterOut": "Exclure",
|
||||
"xpack.threatIntelligence.timeline.addToTimeline": "Ajouter à la chronologie",
|
||||
"xpack.threatIntelligence.timeline.investigateInTimelineButtonIcon": "Investiguer dans la chronologie",
|
||||
"xpack.threatIntelligence.updateStatus.updated": "Mis à jour",
|
||||
"xpack.threatIntelligence.updateStatus.updating": "Mise à jour...",
|
||||
"xpack.securitySolution.threatIntelligence.addToBlockList": "Ajouter une entrée dans la liste noire",
|
||||
"xpack.securitySolution.threatIntelligence.addToExistingCase": "Ajouter à un cas existant",
|
||||
"xpack.securitySolution.threatIntelligence.addToNewCase": "Ajouter au nouveau cas",
|
||||
"xpack.securitySolution.threatIntelligence.blocklist.flyoutTitle": "Ajouter une liste noire",
|
||||
"xpack.securitySolution.threatIntelligence.cases.eventDescription": "ajouté un indicateur de compromis",
|
||||
"xpack.securitySolution.threatIntelligence.cases.indicatorFeedName": "Nom du fil :",
|
||||
"xpack.securitySolution.threatIntelligence.cases.indicatorName": "Nom de l'indicateur :",
|
||||
"xpack.securitySolution.threatIntelligence.cases.indicatorType": "Type d'indicateur :",
|
||||
"xpack.securitySolution.threatIntelligence.common.emptyPage.body1": "Elastic Threat Intelligence facilite l'analyse et l'investigation des menaces potentielles pour la sécurité en regroupant les données de plusieurs sources en un seul endroit.",
|
||||
"xpack.securitySolution.threatIntelligence.common.emptyPage.body2": "Vous pourrez consulter les données de tous les flux Threat Intelligence activés et prendre des mesures à partir de cette page.",
|
||||
"xpack.securitySolution.threatIntelligence.common.emptyPage.body3": "Pour vous lancer avec Elastic Threat Intelligence, activez une ou plusieurs intégrations Threat Intelligence depuis la page Intégrations ou bien ingérez des données avec Filebeat. Pour plus d'informations, consultez la ressource {docsLink}.",
|
||||
"xpack.securitySolution.threatIntelligence.common.emptyPage.buttonText": "Ajouter des intégrations",
|
||||
"xpack.securitySolution.threatIntelligence.common.emptyPage.docsLinkText": "Sécurité de la documentation",
|
||||
"xpack.securitySolution.threatIntelligence.common.emptyPage.imgAlt": "Activer les intégrations Threat Intelligence",
|
||||
"xpack.securitySolution.threatIntelligence.common.emptyPage.title": "Prise en main d’Elastic Threat Intelligence",
|
||||
"xpack.securitySolution.threatIntelligence.empty.description": "Essayer de rechercher sur une période plus longue ou de modifier votre recherche",
|
||||
"xpack.securitySolution.threatIntelligence.empty.title": "Aucun résultat ne correspond à vos critères de recherche.",
|
||||
"xpack.securitySolution.threatIntelligence.field.@timestamp": "@timestamp",
|
||||
"xpack.securitySolution.threatIntelligence.field.threat.feed.name": "Fil",
|
||||
"xpack.securitySolution.threatIntelligence.field.threat.indicator.confidence": "Confiance",
|
||||
"xpack.securitySolution.threatIntelligence.field.threat.indicator.first_seen": "Vu en premier",
|
||||
"xpack.securitySolution.threatIntelligence.field.threat.indicator.last_seen": "Vu en dernier",
|
||||
"xpack.securitySolution.threatIntelligence.field.threat.indicator.marking.tlp": "Marquage TLP",
|
||||
"xpack.securitySolution.threatIntelligence.field.threat.indicator.name": "Indicateur",
|
||||
"xpack.securitySolution.threatIntelligence.field.threat.indicator.type": "Type d’indicateur",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.barChart.popover": "Plus d'actions",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.barchartSection.title": "Tendance",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.fieldSelector.label": "Empiler par",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.fieldsTable.fieldColumnLabel": "Champ",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.fieldsTable.valueColumnLabel": "Valeur",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyout.jsonTabLabel": "JSON",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyout.overviewTabLabel": "Aperçu",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyout.panelSubTitle": "Vu en premier :",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyout.panelTitleWithOverviewTab": "Détails de l'indicateur",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyout.tableTabLabel": "Tableau",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyoutOverviewTable.highlightedFields": "Champs en surbrillance",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyoutOverviewTable.viewAllFieldsInTable": "Afficher tous les champs dans le tableau",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyoutTable.errorMessageBody": "Une erreur s'est produite lors de l'affichage des champs et des valeurs des indicateurs.",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyoutTable.errorMessageTitle": "Impossible d'afficher les informations des indicateurs",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.table.actionColumnLabel": "Actions",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.table.moreActions": "Plus d'actions",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.table.viewDetailsButton": "Afficher les détails",
|
||||
"xpack.securitySolution.threatIntelligence.indicatorNameFieldDescription": "Nom d'affichage de l'indicateur généré pendant le temps d'exécution",
|
||||
"xpack.securitySolution.threatIntelligence.indicators.flyout.take-action.button": "Entreprendre une action",
|
||||
"xpack.securitySolution.threatIntelligence.indicators.table.copyToClipboardLabel": "Copier dans le presse-papiers",
|
||||
"xpack.securitySolution.threatIntelligence.inspectorFlyoutTitle": "Requêtes de recherche des indicateurs",
|
||||
"xpack.securitySolution.threatIntelligence.inspectTitle": "Inspecter",
|
||||
"xpack.securitySolution.threatIntelligence.investigateInTimelineButton": "Investiguer dans la chronologie",
|
||||
"xpack.securitySolution.threatIntelligence.more-actions.popover": "Plus d'actions",
|
||||
"xpack.securitySolution.threatIntelligence.navigation.indicatorsNavItemDescription": "Elastic Threat Intelligence vous aide à voir si vous êtes exposé ou avez été exposé à des menaces connues actuelles ou passées.",
|
||||
"xpack.securitySolution.threatIntelligence.navigation.indicatorsNavItemKeywords": "Indicateurs",
|
||||
"xpack.securitySolution.threatIntelligence.navigation.indicatorsNavItemLabel": "Indicateurs",
|
||||
"xpack.securitySolution.threatIntelligence.navigation.intelligenceNavItemLabel": "Intelligence",
|
||||
"xpack.securitySolution.threatIntelligence.paywall.body": "Démarrez un essai gratuit ou mettez à niveau votre licence vers Enterprise pour utiliser la Threat Intelligence.",
|
||||
"xpack.securitySolution.threatIntelligence.paywall.title": "Toujours plus avec Security !",
|
||||
"xpack.securitySolution.threatIntelligence.paywall.trial": "Démarrer un essai gratuit",
|
||||
"xpack.securitySolution.threatIntelligence.paywall.upgrade": "Mettre à niveau",
|
||||
"xpack.securitySolution.threatIntelligence.queryBar.filterOut": "Exclure",
|
||||
"xpack.securitySolution.threatIntelligence.timeline.addToTimeline": "Ajouter à la chronologie",
|
||||
"xpack.securitySolution.threatIntelligence.timeline.investigateInTimelineButtonIcon": "Investiguer dans la chronologie",
|
||||
"xpack.securitySolution.threatIntelligence.updateStatus.updated": "Mis à jour",
|
||||
"xpack.securitySolution.threatIntelligence.updateStatus.updating": "Mise à jour...",
|
||||
"xpack.timelines.clipboard.copied": "Copié",
|
||||
"xpack.timelines.clipboard.copy": "Copier",
|
||||
"xpack.timelines.clipboard.copy.successToastTitle": "Champ {field} copié dans le presse-papiers",
|
||||
|
|
|
@ -46079,68 +46079,68 @@
|
|||
"xpack.synthetics.windowValueExpression.numberOfChecksPopoverTitleLabel": "チェックの数",
|
||||
"xpack.synthetics.windowValueExpression.numberOfLocPopoverTitleLabel": "場所数",
|
||||
"xpack.synthetics.windowValueExpression.percentLabel": "{numberOfLocations} {numberOfLocations, plural, other {個の場所}}",
|
||||
"xpack.threatIntelligence.addToBlockList": "ブロックリストエントリの追加",
|
||||
"xpack.threatIntelligence.addToExistingCase": "既存のケースに追加",
|
||||
"xpack.threatIntelligence.addToNewCase": "新しいケースに追加",
|
||||
"xpack.threatIntelligence.blocklist.flyoutTitle": "ブロックリストの追加",
|
||||
"xpack.threatIntelligence.cases.eventDescription": "侵害のインジケーターを追加しました",
|
||||
"xpack.threatIntelligence.cases.indicatorFeedName": "フィード名",
|
||||
"xpack.threatIntelligence.cases.indicatorName": "インジケーター名:",
|
||||
"xpack.threatIntelligence.cases.indicatorType": "インジケータータイプ:",
|
||||
"xpack.threatIntelligence.common.emptyPage.body1": "Elastic Threat Intelligenceでは、複数のソースのデータを一元的に集約することで、潜在的なセキュリティ脅威を簡単に分析、調査できます。",
|
||||
"xpack.threatIntelligence.common.emptyPage.body2": "すべてのアクティブな脅威インテリジェンスフィードのデータを表示し、このページからアクションを実行できます。",
|
||||
"xpack.threatIntelligence.common.emptyPage.body3": "Elastic Threat Intelligenceを開始するには、[統合]ページから1つ以上の脅威インテリジェンス統合を有効にするか、Filebeatを使用してデータを取り込みます。詳細については、{docsLink}をご覧ください。",
|
||||
"xpack.threatIntelligence.common.emptyPage.buttonText": "統合の追加",
|
||||
"xpack.threatIntelligence.common.emptyPage.docsLinkText": "セキュリティアプリドキュメント",
|
||||
"xpack.threatIntelligence.common.emptyPage.imgAlt": "脅威インテリジェンス統合を有効にする",
|
||||
"xpack.threatIntelligence.common.emptyPage.title": "Elastic Threat Intelligenceの基本操作",
|
||||
"xpack.threatIntelligence.empty.description": "期間を長くして検索するか、検索を変更してください",
|
||||
"xpack.threatIntelligence.empty.title": "検索条件と一致する結果がありません。",
|
||||
"xpack.threatIntelligence.field.@timestamp": "@timestamp",
|
||||
"xpack.threatIntelligence.field.threat.feed.name": "フィード",
|
||||
"xpack.threatIntelligence.field.threat.indicator.confidence": "信頼度",
|
||||
"xpack.threatIntelligence.field.threat.indicator.first_seen": "初回の認識",
|
||||
"xpack.threatIntelligence.field.threat.indicator.last_seen": "前回の認識",
|
||||
"xpack.threatIntelligence.field.threat.indicator.marking.tlp": "TLPマーキング",
|
||||
"xpack.threatIntelligence.field.threat.indicator.name": "インジケーター",
|
||||
"xpack.threatIntelligence.field.threat.indicator.type": "インジケータータイプ",
|
||||
"xpack.threatIntelligence.indicator.barChart.popover": "さらにアクションを表示",
|
||||
"xpack.threatIntelligence.indicator.barchartSection.title": "傾向",
|
||||
"xpack.threatIntelligence.indicator.fieldSelector.label": "積み上げ",
|
||||
"xpack.threatIntelligence.indicator.fieldsTable.fieldColumnLabel": "フィールド",
|
||||
"xpack.threatIntelligence.indicator.fieldsTable.valueColumnLabel": "値",
|
||||
"xpack.threatIntelligence.indicator.flyout.jsonTabLabel": "JSON",
|
||||
"xpack.threatIntelligence.indicator.flyout.overviewTabLabel": "概要",
|
||||
"xpack.threatIntelligence.indicator.flyout.panelSubTitle": "初回の表示:",
|
||||
"xpack.threatIntelligence.indicator.flyout.panelTitleWithOverviewTab": "インジケーターの詳細",
|
||||
"xpack.threatIntelligence.indicator.flyout.tableTabLabel": "表",
|
||||
"xpack.threatIntelligence.indicator.flyoutOverviewTable.highlightedFields": "ハイライトされたフィールド",
|
||||
"xpack.threatIntelligence.indicator.flyoutOverviewTable.viewAllFieldsInTable": "テーブルのすべてのフィールドを表示",
|
||||
"xpack.threatIntelligence.indicator.flyoutTable.errorMessageBody": "インジケーターフィールドと値の表示エラーが発生しました。",
|
||||
"xpack.threatIntelligence.indicator.flyoutTable.errorMessageTitle": "インジケーター情報を表示できませn",
|
||||
"xpack.threatIntelligence.indicator.table.actionColumnLabel": "アクション",
|
||||
"xpack.threatIntelligence.indicator.table.moreActions": "さらにアクションを表示",
|
||||
"xpack.threatIntelligence.indicator.table.viewDetailsButton": "詳細を表示",
|
||||
"xpack.threatIntelligence.indicatorNameFieldDescription": "実行時に生成されたインジケーター表示名",
|
||||
"xpack.threatIntelligence.indicators.flyout.take-action.button": "アクションを実行",
|
||||
"xpack.threatIntelligence.indicators.table.copyToClipboardLabel": "クリップボードにコピー",
|
||||
"xpack.threatIntelligence.inspectorFlyoutTitle": "インジケーター検索リクエスト",
|
||||
"xpack.threatIntelligence.inspectTitle": "検査",
|
||||
"xpack.threatIntelligence.investigateInTimelineButton": "タイムラインで調査",
|
||||
"xpack.threatIntelligence.more-actions.popover": "さらにアクションを表示",
|
||||
"xpack.threatIntelligence.navigation.indicatorsNavItemDescription": "Elastic threat intelligenceでは、最新の脅威または過去の確認済みの脅威にさらされ、脆弱であるかどうかを確認できます。",
|
||||
"xpack.threatIntelligence.navigation.indicatorsNavItemKeywords": "インジケーター",
|
||||
"xpack.threatIntelligence.navigation.indicatorsNavItemLabel": "インジケーター",
|
||||
"xpack.threatIntelligence.navigation.intelligenceNavItemLabel": "インテリジェンス",
|
||||
"xpack.threatIntelligence.paywall.body": "脅威インテリジェンスを使用するには、無料トライアルを開始するか、ライセンスをEnterpriseにアップグレードしてください。",
|
||||
"xpack.threatIntelligence.paywall.title": "Securityではさまざまなことが可能です!",
|
||||
"xpack.threatIntelligence.paywall.trial": "無料トライアルをはじめる",
|
||||
"xpack.threatIntelligence.paywall.upgrade": "アップグレード",
|
||||
"xpack.threatIntelligence.queryBar.filterOut": "除外",
|
||||
"xpack.threatIntelligence.timeline.addToTimeline": "タイムラインに追加",
|
||||
"xpack.threatIntelligence.timeline.investigateInTimelineButtonIcon": "タイムラインで調査",
|
||||
"xpack.threatIntelligence.updateStatus.updated": "更新しました",
|
||||
"xpack.threatIntelligence.updateStatus.updating": "更新中...",
|
||||
"xpack.securitySolution.threatIntelligence.addToBlockList": "ブロックリストエントリの追加",
|
||||
"xpack.securitySolution.threatIntelligence.addToExistingCase": "既存のケースに追加",
|
||||
"xpack.securitySolution.threatIntelligence.addToNewCase": "新しいケースに追加",
|
||||
"xpack.securitySolution.threatIntelligence.blocklist.flyoutTitle": "ブロックリストの追加",
|
||||
"xpack.securitySolution.threatIntelligence.cases.eventDescription": "侵害のインジケーターを追加しました",
|
||||
"xpack.securitySolution.threatIntelligence.cases.indicatorFeedName": "フィード名",
|
||||
"xpack.securitySolution.threatIntelligence.cases.indicatorName": "インジケーター名:",
|
||||
"xpack.securitySolution.threatIntelligence.cases.indicatorType": "インジケータータイプ:",
|
||||
"xpack.securitySolution.threatIntelligence.common.emptyPage.body1": "Elastic Threat Intelligenceでは、複数のソースのデータを一元的に集約することで、潜在的なセキュリティ脅威を簡単に分析、調査できます。",
|
||||
"xpack.securitySolution.threatIntelligence.common.emptyPage.body2": "すべてのアクティブな脅威インテリジェンスフィードのデータを表示し、このページからアクションを実行できます。",
|
||||
"xpack.securitySolution.threatIntelligence.common.emptyPage.body3": "Elastic Threat Intelligenceを開始するには、[統合]ページから1つ以上の脅威インテリジェンス統合を有効にするか、Filebeatを使用してデータを取り込みます。詳細については、{docsLink}をご覧ください。",
|
||||
"xpack.securitySolution.threatIntelligence.common.emptyPage.buttonText": "統合の追加",
|
||||
"xpack.securitySolution.threatIntelligence.common.emptyPage.docsLinkText": "セキュリティアプリドキュメント",
|
||||
"xpack.securitySolution.threatIntelligence.common.emptyPage.imgAlt": "脅威インテリジェンス統合を有効にする",
|
||||
"xpack.securitySolution.threatIntelligence.common.emptyPage.title": "Elastic Threat Intelligenceの基本操作",
|
||||
"xpack.securitySolution.threatIntelligence.empty.description": "期間を長くして検索するか、検索を変更してください",
|
||||
"xpack.securitySolution.threatIntelligence.empty.title": "検索条件と一致する結果がありません。",
|
||||
"xpack.securitySolution.threatIntelligence.field.@timestamp": "@timestamp",
|
||||
"xpack.securitySolution.threatIntelligence.field.threat.feed.name": "フィード",
|
||||
"xpack.securitySolution.threatIntelligence.field.threat.indicator.confidence": "信頼度",
|
||||
"xpack.securitySolution.threatIntelligence.field.threat.indicator.first_seen": "初回の認識",
|
||||
"xpack.securitySolution.threatIntelligence.field.threat.indicator.last_seen": "前回の認識",
|
||||
"xpack.securitySolution.threatIntelligence.field.threat.indicator.marking.tlp": "TLPマーキング",
|
||||
"xpack.securitySolution.threatIntelligence.field.threat.indicator.name": "インジケーター",
|
||||
"xpack.securitySolution.threatIntelligence.field.threat.indicator.type": "インジケータータイプ",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.barChart.popover": "さらにアクションを表示",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.barchartSection.title": "傾向",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.fieldSelector.label": "積み上げ",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.fieldsTable.fieldColumnLabel": "フィールド",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.fieldsTable.valueColumnLabel": "値",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyout.jsonTabLabel": "JSON",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyout.overviewTabLabel": "概要",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyout.panelSubTitle": "初回の表示:",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyout.panelTitleWithOverviewTab": "インジケーターの詳細",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyout.tableTabLabel": "表",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyoutOverviewTable.highlightedFields": "ハイライトされたフィールド",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyoutOverviewTable.viewAllFieldsInTable": "テーブルのすべてのフィールドを表示",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyoutTable.errorMessageBody": "インジケーターフィールドと値の表示エラーが発生しました。",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyoutTable.errorMessageTitle": "インジケーター情報を表示できませn",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.table.actionColumnLabel": "アクション",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.table.moreActions": "さらにアクションを表示",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.table.viewDetailsButton": "詳細を表示",
|
||||
"xpack.securitySolution.threatIntelligence.indicatorNameFieldDescription": "実行時に生成されたインジケーター表示名",
|
||||
"xpack.securitySolution.threatIntelligence.indicators.flyout.take-action.button": "アクションを実行",
|
||||
"xpack.securitySolution.threatIntelligence.indicators.table.copyToClipboardLabel": "クリップボードにコピー",
|
||||
"xpack.securitySolution.threatIntelligence.inspectorFlyoutTitle": "インジケーター検索リクエスト",
|
||||
"xpack.securitySolution.threatIntelligence.inspectTitle": "検査",
|
||||
"xpack.securitySolution.threatIntelligence.investigateInTimelineButton": "タイムラインで調査",
|
||||
"xpack.securitySolution.threatIntelligence.more-actions.popover": "さらにアクションを表示",
|
||||
"xpack.securitySolution.threatIntelligence.navigation.indicatorsNavItemDescription": "Elastic threat intelligenceでは、最新の脅威または過去の確認済みの脅威にさらされ、脆弱であるかどうかを確認できます。",
|
||||
"xpack.securitySolution.threatIntelligence.navigation.indicatorsNavItemKeywords": "インジケーター",
|
||||
"xpack.securitySolution.threatIntelligence.navigation.indicatorsNavItemLabel": "インジケーター",
|
||||
"xpack.securitySolution.threatIntelligence.navigation.intelligenceNavItemLabel": "インテリジェンス",
|
||||
"xpack.securitySolution.threatIntelligence.paywall.body": "脅威インテリジェンスを使用するには、無料トライアルを開始するか、ライセンスをEnterpriseにアップグレードしてください。",
|
||||
"xpack.securitySolution.threatIntelligence.paywall.title": "Securityではさまざまなことが可能です!",
|
||||
"xpack.securitySolution.threatIntelligence.paywall.trial": "無料トライアルをはじめる",
|
||||
"xpack.securitySolution.threatIntelligence.paywall.upgrade": "アップグレード",
|
||||
"xpack.securitySolution.threatIntelligence.queryBar.filterOut": "除外",
|
||||
"xpack.securitySolution.threatIntelligence.timeline.addToTimeline": "タイムラインに追加",
|
||||
"xpack.securitySolution.threatIntelligence.timeline.investigateInTimelineButtonIcon": "タイムラインで調査",
|
||||
"xpack.securitySolution.threatIntelligence.updateStatus.updated": "更新しました",
|
||||
"xpack.securitySolution.threatIntelligence.updateStatus.updating": "更新中...",
|
||||
"xpack.timelines.clipboard.copied": "コピー完了",
|
||||
"xpack.timelines.clipboard.copy": "コピー",
|
||||
"xpack.timelines.clipboard.copy.successToastTitle": "フィールド{field}をクリップボードにコピーしました",
|
||||
|
|
|
@ -46165,68 +46165,68 @@
|
|||
"xpack.synthetics.windowValueExpression.numberOfChecksPopoverTitleLabel": "检查数目",
|
||||
"xpack.synthetics.windowValueExpression.numberOfLocPopoverTitleLabel": "位置数",
|
||||
"xpack.synthetics.windowValueExpression.percentLabel": "{numberOfLocations} 个{numberOfLocations, plural, other {位置}}",
|
||||
"xpack.threatIntelligence.addToBlockList": "添加阻止列表条目",
|
||||
"xpack.threatIntelligence.addToExistingCase": "添加到现有案例",
|
||||
"xpack.threatIntelligence.addToNewCase": "添加到新案例",
|
||||
"xpack.threatIntelligence.blocklist.flyoutTitle": "添加阻止列表",
|
||||
"xpack.threatIntelligence.cases.eventDescription": "已添加受损指标",
|
||||
"xpack.threatIntelligence.cases.indicatorFeedName": "源名称:",
|
||||
"xpack.threatIntelligence.cases.indicatorName": "指标名称:",
|
||||
"xpack.threatIntelligence.cases.indicatorType": "指标类型:",
|
||||
"xpack.threatIntelligence.common.emptyPage.body1": "利用 Elastic 威胁情报,可以通过将多个来源的数据聚合到一个位置,轻松分析和调查潜在的安全威胁。",
|
||||
"xpack.threatIntelligence.common.emptyPage.body2": "您将可以查看来自所有已激活威胁情报馈送的数据,并从此页面执行操作。",
|
||||
"xpack.threatIntelligence.common.emptyPage.body3": "要开始使用 Elastic 威胁情报,请从“集成”页面启用一个或多个威胁情报集成,或使用 Filebeat 采集数据。有关更多信息,请查看 {docsLink}。",
|
||||
"xpack.threatIntelligence.common.emptyPage.buttonText": "添加集成",
|
||||
"xpack.threatIntelligence.common.emptyPage.docsLinkText": "Security 应用文档",
|
||||
"xpack.threatIntelligence.common.emptyPage.imgAlt": "启用威胁情报集成",
|
||||
"xpack.threatIntelligence.common.emptyPage.title": "Elastic 威胁情报入门",
|
||||
"xpack.threatIntelligence.empty.description": "尝试搜索更长的时间段或修改您的搜索",
|
||||
"xpack.threatIntelligence.empty.title": "没有任何结果匹配您的搜索条件",
|
||||
"xpack.threatIntelligence.field.@timestamp": "@timestamp",
|
||||
"xpack.threatIntelligence.field.threat.feed.name": "馈送",
|
||||
"xpack.threatIntelligence.field.threat.indicator.confidence": "置信度",
|
||||
"xpack.threatIntelligence.field.threat.indicator.first_seen": "首次看到时间",
|
||||
"xpack.threatIntelligence.field.threat.indicator.last_seen": "最后看到时间",
|
||||
"xpack.threatIntelligence.field.threat.indicator.marking.tlp": "TLP 标记",
|
||||
"xpack.threatIntelligence.field.threat.indicator.name": "指标",
|
||||
"xpack.threatIntelligence.field.threat.indicator.type": "指标类型",
|
||||
"xpack.threatIntelligence.indicator.barChart.popover": "更多操作",
|
||||
"xpack.threatIntelligence.indicator.barchartSection.title": "趋势",
|
||||
"xpack.threatIntelligence.indicator.fieldSelector.label": "堆叠依据",
|
||||
"xpack.threatIntelligence.indicator.fieldsTable.fieldColumnLabel": "字段",
|
||||
"xpack.threatIntelligence.indicator.fieldsTable.valueColumnLabel": "值",
|
||||
"xpack.threatIntelligence.indicator.flyout.jsonTabLabel": "JSON",
|
||||
"xpack.threatIntelligence.indicator.flyout.overviewTabLabel": "概览",
|
||||
"xpack.threatIntelligence.indicator.flyout.panelSubTitle": "首次看到时间:",
|
||||
"xpack.threatIntelligence.indicator.flyout.panelTitleWithOverviewTab": "指标详情",
|
||||
"xpack.threatIntelligence.indicator.flyout.tableTabLabel": "表",
|
||||
"xpack.threatIntelligence.indicator.flyoutOverviewTable.highlightedFields": "突出显示的字段",
|
||||
"xpack.threatIntelligence.indicator.flyoutOverviewTable.viewAllFieldsInTable": "查看表中的所有字段",
|
||||
"xpack.threatIntelligence.indicator.flyoutTable.errorMessageBody": "显示指标字段和值时出现错误。",
|
||||
"xpack.threatIntelligence.indicator.flyoutTable.errorMessageTitle": "无法显示指标信息",
|
||||
"xpack.threatIntelligence.indicator.table.actionColumnLabel": "操作",
|
||||
"xpack.threatIntelligence.indicator.table.moreActions": "更多操作",
|
||||
"xpack.threatIntelligence.indicator.table.viewDetailsButton": "查看详情",
|
||||
"xpack.threatIntelligence.indicatorNameFieldDescription": "在运行时中生成的指标显示名称",
|
||||
"xpack.threatIntelligence.indicators.flyout.take-action.button": "采取操作",
|
||||
"xpack.threatIntelligence.indicators.table.copyToClipboardLabel": "复制到剪贴板",
|
||||
"xpack.threatIntelligence.inspectorFlyoutTitle": "指标搜索请求",
|
||||
"xpack.threatIntelligence.inspectTitle": "检查",
|
||||
"xpack.threatIntelligence.investigateInTimelineButton": "在时间线中调查",
|
||||
"xpack.threatIntelligence.more-actions.popover": "更多操作",
|
||||
"xpack.threatIntelligence.navigation.indicatorsNavItemDescription": "Elastic 威胁情报有助于您了解您是否易于受到或已面临当前或历史上的已知威胁。",
|
||||
"xpack.threatIntelligence.navigation.indicatorsNavItemKeywords": "指标",
|
||||
"xpack.threatIntelligence.navigation.indicatorsNavItemLabel": "指标",
|
||||
"xpack.threatIntelligence.navigation.intelligenceNavItemLabel": "情报",
|
||||
"xpack.threatIntelligence.paywall.body": "开始免费试用或将许可证升级到企业版以使用威胁情报。",
|
||||
"xpack.threatIntelligence.paywall.title": "Security 让您事半功倍!",
|
||||
"xpack.threatIntelligence.paywall.trial": "开始免费试用",
|
||||
"xpack.threatIntelligence.paywall.upgrade": "升级",
|
||||
"xpack.threatIntelligence.queryBar.filterOut": "筛除",
|
||||
"xpack.threatIntelligence.timeline.addToTimeline": "添加到时间线",
|
||||
"xpack.threatIntelligence.timeline.investigateInTimelineButtonIcon": "在时间线中调查",
|
||||
"xpack.threatIntelligence.updateStatus.updated": "已更新",
|
||||
"xpack.threatIntelligence.updateStatus.updating": "正在更新......",
|
||||
"xpack.securitySolution.threatIntelligence.addToBlockList": "添加阻止列表条目",
|
||||
"xpack.securitySolution.threatIntelligence.addToExistingCase": "添加到现有案例",
|
||||
"xpack.securitySolution.threatIntelligence.addToNewCase": "添加到新案例",
|
||||
"xpack.securitySolution.threatIntelligence.blocklist.flyoutTitle": "添加阻止列表",
|
||||
"xpack.securitySolution.threatIntelligence.cases.eventDescription": "已添加受损指标",
|
||||
"xpack.securitySolution.threatIntelligence.cases.indicatorFeedName": "源名称:",
|
||||
"xpack.securitySolution.threatIntelligence.cases.indicatorName": "指标名称:",
|
||||
"xpack.securitySolution.threatIntelligence.cases.indicatorType": "指标类型:",
|
||||
"xpack.securitySolution.threatIntelligence.common.emptyPage.body1": "利用 Elastic 威胁情报,可以通过将多个来源的数据聚合到一个位置,轻松分析和调查潜在的安全威胁。",
|
||||
"xpack.securitySolution.threatIntelligence.common.emptyPage.body2": "您将可以查看来自所有已激活威胁情报馈送的数据,并从此页面执行操作。",
|
||||
"xpack.securitySolution.threatIntelligence.common.emptyPage.body3": "要开始使用 Elastic 威胁情报,请从“集成”页面启用一个或多个威胁情报集成,或使用 Filebeat 采集数据。有关更多信息,请查看 {docsLink}。",
|
||||
"xpack.securitySolution.threatIntelligence.common.emptyPage.buttonText": "添加集成",
|
||||
"xpack.securitySolution.threatIntelligence.common.emptyPage.docsLinkText": "Security 应用文档",
|
||||
"xpack.securitySolution.threatIntelligence.common.emptyPage.imgAlt": "启用威胁情报集成",
|
||||
"xpack.securitySolution.threatIntelligence.common.emptyPage.title": "Elastic 威胁情报入门",
|
||||
"xpack.securitySolution.threatIntelligence.empty.description": "尝试搜索更长的时间段或修改您的搜索",
|
||||
"xpack.securitySolution.threatIntelligence.empty.title": "没有任何结果匹配您的搜索条件",
|
||||
"xpack.securitySolution.threatIntelligence.field.@timestamp": "@timestamp",
|
||||
"xpack.securitySolution.threatIntelligence.field.threat.feed.name": "馈送",
|
||||
"xpack.securitySolution.threatIntelligence.field.threat.indicator.confidence": "置信度",
|
||||
"xpack.securitySolution.threatIntelligence.field.threat.indicator.first_seen": "首次看到时间",
|
||||
"xpack.securitySolution.threatIntelligence.field.threat.indicator.last_seen": "最后看到时间",
|
||||
"xpack.securitySolution.threatIntelligence.field.threat.indicator.marking.tlp": "TLP 标记",
|
||||
"xpack.securitySolution.threatIntelligence.field.threat.indicator.name": "指标",
|
||||
"xpack.securitySolution.threatIntelligence.field.threat.indicator.type": "指标类型",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.barChart.popover": "更多操作",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.barchartSection.title": "趋势",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.fieldSelector.label": "堆叠依据",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.fieldsTable.fieldColumnLabel": "字段",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.fieldsTable.valueColumnLabel": "值",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyout.jsonTabLabel": "JSON",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyout.overviewTabLabel": "概览",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyout.panelSubTitle": "首次看到时间:",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyout.panelTitleWithOverviewTab": "指标详情",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyout.tableTabLabel": "表",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyoutOverviewTable.highlightedFields": "突出显示的字段",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyoutOverviewTable.viewAllFieldsInTable": "查看表中的所有字段",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyoutTable.errorMessageBody": "显示指标字段和值时出现错误。",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.flyoutTable.errorMessageTitle": "无法显示指标信息",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.table.actionColumnLabel": "操作",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.table.moreActions": "更多操作",
|
||||
"xpack.securitySolution.threatIntelligence.indicator.table.viewDetailsButton": "查看详情",
|
||||
"xpack.securitySolution.threatIntelligence.indicatorNameFieldDescription": "在运行时中生成的指标显示名称",
|
||||
"xpack.securitySolution.threatIntelligence.indicators.flyout.take-action.button": "采取操作",
|
||||
"xpack.securitySolution.threatIntelligence.indicators.table.copyToClipboardLabel": "复制到剪贴板",
|
||||
"xpack.securitySolution.threatIntelligence.inspectorFlyoutTitle": "指标搜索请求",
|
||||
"xpack.securitySolution.threatIntelligence.inspectTitle": "检查",
|
||||
"xpack.securitySolution.threatIntelligence.investigateInTimelineButton": "在时间线中调查",
|
||||
"xpack.securitySolution.threatIntelligence.more-actions.popover": "更多操作",
|
||||
"xpack.securitySolution.threatIntelligence.navigation.indicatorsNavItemDescription": "Elastic 威胁情报有助于您了解您是否易于受到或已面临当前或历史上的已知威胁。",
|
||||
"xpack.securitySolution.threatIntelligence.navigation.indicatorsNavItemKeywords": "指标",
|
||||
"xpack.securitySolution.threatIntelligence.navigation.indicatorsNavItemLabel": "指标",
|
||||
"xpack.securitySolution.threatIntelligence.navigation.intelligenceNavItemLabel": "情报",
|
||||
"xpack.securitySolution.threatIntelligence.paywall.body": "开始免费试用或将许可证升级到企业版以使用威胁情报。",
|
||||
"xpack.securitySolution.threatIntelligence.paywall.title": "Security 让您事半功倍!",
|
||||
"xpack.securitySolution.threatIntelligence.paywall.trial": "开始免费试用",
|
||||
"xpack.securitySolution.threatIntelligence.paywall.upgrade": "升级",
|
||||
"xpack.securitySolution.threatIntelligence.queryBar.filterOut": "筛除",
|
||||
"xpack.securitySolution.threatIntelligence.timeline.addToTimeline": "添加到时间线",
|
||||
"xpack.securitySolution.threatIntelligence.timeline.investigateInTimelineButtonIcon": "在时间线中调查",
|
||||
"xpack.securitySolution.threatIntelligence.updateStatus.updated": "已更新",
|
||||
"xpack.securitySolution.threatIntelligence.updateStatus.updating": "正在更新......",
|
||||
"xpack.timelines.clipboard.copied": "已复制",
|
||||
"xpack.timelines.clipboard.copy": "复制",
|
||||
"xpack.timelines.clipboard.copy.successToastTitle": "已将字段 {field} 复制到剪贴板",
|
||||
|
|
|
@ -13,8 +13,8 @@ export const BARCHART_AGGREGATION_NAME = 'barchartAggregation';
|
|||
* Used inside custom search strategy
|
||||
*/
|
||||
export enum FactoryQueryType {
|
||||
IndicatorGrid = 'indicatorGrid',
|
||||
Barchart = 'barchart',
|
||||
IndicatorGrid = 'threatIntelligenceIndicatorGrid',
|
||||
Barchart = 'threatIntelligenceBarchart',
|
||||
}
|
||||
|
||||
export const CASE_ATTACHMENT_TYPE_ID = 'indicator';
|
|
@ -39,7 +39,6 @@
|
|||
"sessionView",
|
||||
"spaces",
|
||||
"taskManager",
|
||||
"threatIntelligence",
|
||||
"timelines",
|
||||
"triggersActionsUi",
|
||||
"uiActions",
|
||||
|
|
|
@ -26,6 +26,7 @@ import type {
|
|||
} from '@kbn/discover-shared-plugin/public/services/discover_features';
|
||||
import { ProductFeatureSecurityKey } from '@kbn/security-solution-features/keys';
|
||||
import { ProductFeatureAssistantKey } from '@kbn/security-solution-features/src/product_features_keys';
|
||||
import type { ExternalReferenceAttachmentType } from '@kbn/cases-plugin/public/client/attachment_framework/types';
|
||||
import { getLazyCloudSecurityPosturePliAuthBlockExtension } from './cloud_security_posture/lazy_cloud_security_posture_pli_auth_block_extension';
|
||||
import { getLazyEndpointAgentTamperProtectionExtension } from './management/pages/policy/view/ingest_manager_integration/lazy_endpoint_agent_tamper_protection_extension';
|
||||
import type {
|
||||
|
@ -66,6 +67,7 @@ import { PluginContract } from './plugin_contract';
|
|||
import { PluginServices } from './plugin_services';
|
||||
import { getExternalReferenceAttachmentEndpointRegular } from './cases/attachments/external_reference';
|
||||
import { hasAccessToSecuritySolution } from './helpers_access';
|
||||
import { generateAttachmentType } from './threat_intelligence/modules/cases/utils/attachments';
|
||||
|
||||
export class Plugin implements IPlugin<PluginSetup, PluginStart, SetupPlugins, StartPlugins> {
|
||||
private config: SecuritySolutionUiConfigType;
|
||||
|
@ -232,6 +234,9 @@ export class Plugin implements IPlugin<PluginSetup, PluginStart, SetupPlugins, S
|
|||
getExternalReferenceAttachmentEndpointRegular()
|
||||
);
|
||||
|
||||
const externalAttachmentType: ExternalReferenceAttachmentType = generateAttachmentType();
|
||||
cases?.attachmentFramework?.registerExternalReference(externalAttachmentType);
|
||||
|
||||
this.registerDiscoverSharedFeatures(core, plugins);
|
||||
|
||||
return this.contract.getSetupContract();
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
|
||||
Elastic Threat Intelligence makes it easy to analyze and investigate potential security threats by aggregating data from multiple sources in one place. You’ll be able to view data from all activated threat intelligence feeds and take action.
|
||||
|
||||
### Where to find the UI for this plugin?
|
||||
|
||||
The Threat Intelligence UI is displayed in Kibana Security, under the Explore section.
|
||||
|
||||
## Development setup
|
||||
|
||||
### Kibana development in general
|
||||
|
@ -63,29 +59,3 @@ node scripts/generate_indicators.js
|
|||
```
|
||||
|
||||
see the file in order to adjust the amount of indicators generated. The default is one million.
|
||||
|
||||
## E2E
|
||||
|
||||
### Running locally
|
||||
|
||||
Cypress tests are integrated with the Security Solution ones. Please refer to https://github.com/elastic/kibana/blob/main/x-pack/test/security_solution_cypress/cypress/README.md for more information
|
||||
|
||||
## FAQ
|
||||
|
||||
### How is the Threat Intelligence code loaded in Kibana?
|
||||
|
||||
The Threat Intelligence plugin is loaded lazily within the [security_solution](https://github.com/elastic/kibana/tree/main/x-pack/solutions/security/plugins/security_solution) plugin,
|
||||
from `x-pack/solutions/security/plugins/security_solution/public/threat_intelligence` owned by the Threat Hunting Investigations Team.
|
||||
|
||||
## QA and demo for implemented features
|
||||
|
||||
One way to QA and demo the feature merged into `main` branch is to run the latest `main` locally.
|
||||
Another option is to deploy a Staging instance. For Staging environment snapshots are being build every night with the latest state of the `main` branch. More documentation can be found [here](https://cloud.elastic.dev/environments/Staging/#automatic-termination-of-staging-deployments)
|
||||
|
||||
## Contributing
|
||||
|
||||
See [CONTRIBUTING.md](https://github.com/elastic/kibana/blob/main/x-pack/solutions/security/plugins/threat_intelligence/CONTRIBUTING.md) for information on contributing.
|
||||
|
||||
## Issues
|
||||
|
||||
Please report any issues in [this GitHub project](https://github.com/orgs/elastic/projects/758/).
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public';
|
||||
import { CoreStart } from '@kbn/core/public';
|
||||
import type { CoreStart } from '@kbn/core/public';
|
||||
import { mockUiSettingsService } from '../mocks/mock_kibana_ui_settings_service';
|
||||
import { DateFormatter } from './date_formatter';
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import moment from 'moment';
|
||||
import React, { VFC } from 'react';
|
||||
import React, { type FC } from 'react';
|
||||
import { EMPTY_VALUE } from '../constants/common';
|
||||
import { dateFormatter } from '../utils/dates';
|
||||
import { useDateFormat, useTimeZone } from '../hooks/use_kibana_ui_settings';
|
||||
|
@ -18,7 +18,7 @@ export interface DateFormatterProps {
|
|||
dateFormat?: string;
|
||||
}
|
||||
|
||||
export const DateFormatter: VFC<DateFormatterProps> = ({ date, dateFormat }) => {
|
||||
export const DateFormatter: FC<DateFormatterProps> = ({ date, dateFormat }) => {
|
||||
const userTimeZone = useTimeZone();
|
||||
const userFormat = useDateFormat();
|
||||
|
|
@ -32,14 +32,14 @@ export const EmptyState: React.FC<{ height?: keyof typeof heights }> = ({ height
|
|||
<EuiTitle>
|
||||
<h3>
|
||||
<FormattedMessage
|
||||
id="xpack.threatIntelligence.empty.title"
|
||||
id="xpack.securitySolution.threatIntelligence.empty.title"
|
||||
defaultMessage="No results match your search criteria"
|
||||
/>
|
||||
</h3>
|
||||
</EuiTitle>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.threatIntelligence.empty.description"
|
||||
id="xpack.securitySolution.threatIntelligence.empty.description"
|
||||
defaultMessage="Try searching over a longer period of time or modifying your search"
|
||||
/>
|
||||
</p>
|
|
@ -18,11 +18,11 @@ export default {
|
|||
|
||||
export const Default: StoryFn = () => {
|
||||
const title = 'Title with border below';
|
||||
const children = <EuiText>Content with border above</EuiText>;
|
||||
const children = <EuiText>{'Content with border above'}</EuiText>;
|
||||
|
||||
return (
|
||||
<StoryProvidersComponent>
|
||||
<DefaultPageLayout pageTitle={title} children={children} />
|
||||
<DefaultPageLayout pageTitle={title}>{children}</DefaultPageLayout>
|
||||
</StoryProvidersComponent>
|
||||
);
|
||||
};
|
||||
|
@ -30,11 +30,13 @@ export const Default: StoryFn = () => {
|
|||
export const NoBorder: StoryFn = () => {
|
||||
const title = 'Title without border';
|
||||
const border = false;
|
||||
const children = <EuiText>Content without border</EuiText>;
|
||||
const children = <EuiText>{'Content without border'}</EuiText>;
|
||||
|
||||
return (
|
||||
<StoryProvidersComponent>
|
||||
<DefaultPageLayout pageTitle={title} border={border} children={children} />
|
||||
<DefaultPageLayout pageTitle={title} border={border}>
|
||||
{children}
|
||||
</DefaultPageLayout>
|
||||
</StoryProvidersComponent>
|
||||
);
|
||||
};
|
|
@ -6,7 +6,8 @@
|
|||
*/
|
||||
|
||||
import { EuiPageHeader, EuiPageHeaderSection, EuiSpacer, EuiText } from '@elastic/eui';
|
||||
import React, { FC, PropsWithChildren, ReactNode } from 'react';
|
||||
import type { FC, PropsWithChildren, ReactNode } from 'react';
|
||||
import React from 'react';
|
||||
import { SecuritySolutionPageWrapper } from '../containers/security_solution_page_wrapper';
|
||||
import { TITLE_TEST_ID } from './test_ids';
|
||||
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 126 KiB |
|
@ -5,7 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { VFC } from 'react';
|
||||
import type { FC } from 'react';
|
||||
import React from 'react';
|
||||
import {
|
||||
EuiButton,
|
||||
EuiButtonEmpty,
|
||||
|
@ -15,9 +16,9 @@ import {
|
|||
EuiIcon,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { useKibana } from '../hooks/use_kibana';
|
||||
import { useKibana } from '../../common/lib/kibana';
|
||||
|
||||
export const Paywall: VFC = () => {
|
||||
export const Paywall: FC = () => {
|
||||
const {
|
||||
services: { application },
|
||||
} = useKibana();
|
||||
|
@ -29,7 +30,7 @@ export const Paywall: VFC = () => {
|
|||
title={
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="xpack.threatIntelligence.paywall.title"
|
||||
id="xpack.securitySolution.threatIntelligence.paywall.title"
|
||||
defaultMessage="Do more with Security!"
|
||||
/>
|
||||
</h2>
|
||||
|
@ -37,7 +38,7 @@ export const Paywall: VFC = () => {
|
|||
body={
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.threatIntelligence.paywall.body"
|
||||
id="xpack.securitySolution.threatIntelligence.paywall.body"
|
||||
defaultMessage="Start a free trial or upgrade your license to Enterprise to use threat intelligence."
|
||||
/>
|
||||
</p>
|
||||
|
@ -48,7 +49,7 @@ export const Paywall: VFC = () => {
|
|||
<div>
|
||||
<EuiButton color="primary" fill href="https://www.elastic.co/subscriptions">
|
||||
<FormattedMessage
|
||||
id="xpack.threatIntelligence.paywall.upgrade"
|
||||
id="xpack.securitySolution.threatIntelligence.paywall.upgrade"
|
||||
defaultMessage="Upgrade"
|
||||
/>
|
||||
</EuiButton>
|
||||
|
@ -64,7 +65,7 @@ export const Paywall: VFC = () => {
|
|||
}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.threatIntelligence.paywall.trial"
|
||||
id="xpack.securitySolution.threatIntelligence.paywall.trial"
|
||||
defaultMessage="Start a free trial"
|
||||
/>
|
||||
</EuiButtonEmpty>
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* 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 { i18n } from '@kbn/i18n';
|
||||
|
||||
export const UPDATING = i18n.translate(
|
||||
'xpack.securitySolution.threatIntelligence.updateStatus.updating',
|
||||
{
|
||||
defaultMessage: 'Updating...',
|
||||
}
|
||||
);
|
||||
|
||||
export const UPDATED = i18n.translate(
|
||||
'xpack.securitySolution.threatIntelligence.updateStatus.updated',
|
||||
{
|
||||
defaultMessage: 'Updated',
|
||||
}
|
||||
);
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { TIPage, TIPageProperties } from '../types';
|
||||
import type { TIPage, TIPageProperties } from '../types';
|
||||
import { DESCRIPTION, INDICATORS, INTELLIGENCE } from './translations';
|
||||
|
||||
/**
|
|
@ -8,21 +8,21 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export const INDICATORS = i18n.translate(
|
||||
'xpack.threatIntelligence.navigation.indicatorsNavItemLabel',
|
||||
'xpack.securitySolution.threatIntelligence.navigation.indicatorsNavItemLabel',
|
||||
{
|
||||
defaultMessage: 'Indicators',
|
||||
}
|
||||
);
|
||||
|
||||
export const INTELLIGENCE = i18n.translate(
|
||||
'xpack.threatIntelligence.navigation.intelligenceNavItemLabel',
|
||||
'xpack.securitySolution.threatIntelligence.navigation.intelligenceNavItemLabel',
|
||||
{
|
||||
defaultMessage: 'Intelligence',
|
||||
}
|
||||
);
|
||||
|
||||
export const DESCRIPTION = i18n.translate(
|
||||
'xpack.threatIntelligence.navigation.indicatorsNavItemDescription',
|
||||
'xpack.securitySolution.threatIntelligence.navigation.indicatorsNavItemDescription',
|
||||
{
|
||||
defaultMessage:
|
||||
'Elastic threat intelligence helps you see if you are open to or have been subject to current or historical known threats.',
|
||||
|
@ -30,7 +30,7 @@ export const DESCRIPTION = i18n.translate(
|
|||
);
|
||||
|
||||
export const KEYWORDS = i18n.translate(
|
||||
'xpack.threatIntelligence.navigation.indicatorsNavItemKeywords',
|
||||
'xpack.securitySolution.threatIntelligence.navigation.indicatorsNavItemKeywords',
|
||||
{
|
||||
defaultMessage: 'Indicators',
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* 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 React, { type ReactNode } from 'react';
|
||||
import { EMPTY_PAGE_SECURITY_TEMPLATE } from '../../mocks/test_providers';
|
||||
|
||||
export const SecuritySolutionPluginTemplateWrapper = (props: {
|
||||
children?: ReactNode;
|
||||
emptyPageBody: ReactNode;
|
||||
isEmptyState: boolean;
|
||||
}) => (
|
||||
<div data-test-subj={EMPTY_PAGE_SECURITY_TEMPLATE}>
|
||||
{props.isEmptyState ? props.emptyPageBody : props.children}
|
||||
</div>
|
||||
);
|
|
@ -8,27 +8,24 @@
|
|||
import { render, screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { EMPTY_PAGE_SECURITY_TEMPLATE, TestProvidersComponent } from '../mocks/test_providers';
|
||||
import { SecuritySolutionPluginContext } from '../types';
|
||||
import { SecuritySolutionContext } from './security_solution_context';
|
||||
import { EnterpriseGuard } from './enterprise_guard';
|
||||
import { useSecurityContext } from '../hooks/use_security_context';
|
||||
|
||||
jest.mock('./security_solution_plugin_template_wrapper');
|
||||
jest.mock('../hooks/use_security_context');
|
||||
|
||||
describe('<EnterpriseGuard />', () => {
|
||||
describe('when on enterprise plan', () => {
|
||||
beforeEach(() => {
|
||||
jest.mocked(useSecurityContext().licenseService.isEnterprise).mockReturnValue(true);
|
||||
});
|
||||
|
||||
it('should render specified children', () => {
|
||||
render(
|
||||
<TestProvidersComponent>
|
||||
<SecuritySolutionContext.Provider
|
||||
value={
|
||||
{
|
||||
licenseService: { isEnterprise: jest.fn().mockReturnValue(true) },
|
||||
} as unknown as SecuritySolutionPluginContext
|
||||
}
|
||||
>
|
||||
<EnterpriseGuard>
|
||||
<div>enterprise only content</div>
|
||||
</EnterpriseGuard>
|
||||
</SecuritySolutionContext.Provider>
|
||||
</TestProvidersComponent>
|
||||
<EnterpriseGuard>
|
||||
<div>{'enterprise only content'}</div>
|
||||
</EnterpriseGuard>,
|
||||
{ wrapper: TestProvidersComponent }
|
||||
);
|
||||
|
||||
expect(screen.queryByText('enterprise only content')).toBeInTheDocument();
|
||||
|
@ -38,21 +35,16 @@ describe('<EnterpriseGuard />', () => {
|
|||
});
|
||||
|
||||
describe('when not on enterprise plan', () => {
|
||||
it('should render specified children', () => {
|
||||
beforeEach(() => {
|
||||
jest.mocked(useSecurityContext().licenseService.isEnterprise).mockReturnValue(false);
|
||||
});
|
||||
|
||||
it('should render the paywall', () => {
|
||||
render(
|
||||
<TestProvidersComponent>
|
||||
<SecuritySolutionContext.Provider
|
||||
value={
|
||||
{
|
||||
licenseService: { isEnterprise: jest.fn().mockReturnValue(false) },
|
||||
} as unknown as SecuritySolutionPluginContext
|
||||
}
|
||||
>
|
||||
<EnterpriseGuard>
|
||||
<div>enterprise only content</div>
|
||||
</EnterpriseGuard>
|
||||
</SecuritySolutionContext.Provider>
|
||||
</TestProvidersComponent>
|
||||
<EnterpriseGuard>
|
||||
<div>{'enterprise only content'}</div>
|
||||
</EnterpriseGuard>,
|
||||
{ wrapper: TestProvidersComponent }
|
||||
);
|
||||
|
||||
expect(screen.queryByText('enterprise only content')).not.toBeInTheDocument();
|
|
@ -5,7 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { memo, PropsWithChildren } from 'react';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
import React, { memo } from 'react';
|
||||
|
||||
import { Paywall } from '../components/paywall';
|
||||
import { useSecurityContext } from '../hooks/use_security_context';
|
||||
|
@ -20,3 +21,5 @@ export const EnterpriseGuard = memo<PropsWithChildren<unknown>>(({ children }) =
|
|||
|
||||
return <SecuritySolutionPluginTemplateWrapper isEmptyState emptyPageBody={<Paywall />} />;
|
||||
});
|
||||
|
||||
EnterpriseGuard.displayName = 'EnterpriseGuard';
|
|
@ -5,8 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { createContext, FC, PropsWithChildren, useMemo } from 'react';
|
||||
import { useSourcererDataView } from '../modules/indicators/hooks/use_sourcerer_data_view';
|
||||
import type { FC, PropsWithChildren } from 'react';
|
||||
import React, { createContext, useMemo } from 'react';
|
||||
import { useTIDataView } from '../modules/indicators/hooks/use_ti_data_view';
|
||||
|
||||
export type FieldTypesContextValue = Record<string, string | undefined>;
|
||||
|
||||
|
@ -18,7 +19,7 @@ export const FieldTypesContext = createContext<FieldTypesContextValue | undefine
|
|||
export const FieldTypesProvider: FC<PropsWithChildren<unknown>> = ({ children }) => {
|
||||
const {
|
||||
sourcererDataView: { fields = {} },
|
||||
} = useSourcererDataView();
|
||||
} = useTIDataView();
|
||||
|
||||
// field name to field type map to allow the cell_renderer to format dates
|
||||
const fieldTypes: FieldTypesContextValue = useMemo(
|
|
@ -5,13 +5,14 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { memo, useMemo, VFC } from 'react';
|
||||
import type { FC } from 'react';
|
||||
import React, { memo, useMemo } from 'react';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { CasesPermissions } from '@kbn/cases-plugin/common';
|
||||
import type { CasesPermissions } from '@kbn/cases-plugin/common';
|
||||
import { IndicatorsPage } from '../modules/indicators/pages/indicators';
|
||||
import { IntegrationsGuard } from './integrations_guard';
|
||||
import { SecuritySolutionPluginTemplateWrapper } from './security_solution_plugin_template_wrapper';
|
||||
import { useKibana } from '../hooks/use_kibana';
|
||||
import { useKibana } from '../../common/lib/kibana';
|
||||
|
||||
export const APP_ID = 'securitySolution';
|
||||
|
||||
|
@ -19,7 +20,7 @@ const queryClient = new QueryClient();
|
|||
|
||||
const casesContextOwner = [APP_ID];
|
||||
|
||||
export const IndicatorsPageWrapper: VFC = () => {
|
||||
export const IndicatorsPageWrapper: FC = () => {
|
||||
const { cases } = useKibana().services;
|
||||
const CasesContext = useMemo(() => cases.ui.getCasesContext(), [cases.ui]);
|
||||
const permissions: CasesPermissions = useMemo(() => cases.helpers.canUseCases(), [cases.helpers]);
|
|
@ -6,7 +6,8 @@
|
|||
*/
|
||||
|
||||
import { RequestAdapter } from '@kbn/inspector-plugin/common';
|
||||
import React, { createContext, FC, PropsWithChildren, useMemo } from 'react';
|
||||
import type { FC, PropsWithChildren } from 'react';
|
||||
import React, { createContext, useMemo } from 'react';
|
||||
|
||||
export interface InspectorContextValue {
|
||||
requests: RequestAdapter;
|
|
@ -5,12 +5,13 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { UseQueryResult } from '@tanstack/react-query';
|
||||
import type { UseQueryResult } from '@tanstack/react-query';
|
||||
import { render } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { IntegrationsGuard } from './integrations_guard';
|
||||
import { EMPTY_PAGE_SECURITY_TEMPLATE, TestProvidersComponent } from '../mocks/test_providers';
|
||||
import { Integration, useIntegrations } from '../hooks/use_integrations';
|
||||
import type { Integration } from '../hooks/use_integrations';
|
||||
import { useIntegrations } from '../hooks/use_integrations';
|
||||
import { useIntegrationsPageLink } from '../hooks/use_integrations_page_link';
|
||||
import { useTIDocumentationLink } from '../hooks/use_documentation_link';
|
||||
import { useIndicatorsTotalCount } from '../modules/indicators/hooks/use_total_count';
|
||||
|
@ -22,6 +23,7 @@ jest.mock('../modules/indicators/hooks/use_total_count');
|
|||
jest.mock('../hooks/use_integrations_page_link');
|
||||
jest.mock('../hooks/use_documentation_link');
|
||||
jest.mock('../hooks/use_integrations');
|
||||
jest.mock('./security_solution_plugin_template_wrapper');
|
||||
|
||||
describe('IntegrationsGuard', () => {
|
||||
it('should render loading when indicator count and integrations are being loaded', async () => {
|
||||
|
@ -42,9 +44,12 @@ describe('IntegrationsGuard', () => {
|
|||
data: [],
|
||||
} as unknown as UseQueryResult<Integration[]>);
|
||||
|
||||
const { getByTestId } = render(<IntegrationsGuard>should be restricted</IntegrationsGuard>, {
|
||||
wrapper: TestProvidersComponent,
|
||||
});
|
||||
const { getByTestId } = render(
|
||||
<IntegrationsGuard>{'should be restricted'}</IntegrationsGuard>,
|
||||
{
|
||||
wrapper: TestProvidersComponent,
|
||||
}
|
||||
);
|
||||
|
||||
expect(getByTestId(LOADING_LOGO_TEST_ID)).toBeInTheDocument();
|
||||
expect(getByTestId(EMPTY_PAGE_SECURITY_TEMPLATE)).toBeInTheDocument();
|
||||
|
@ -68,9 +73,12 @@ describe('IntegrationsGuard', () => {
|
|||
data: [],
|
||||
} as unknown as UseQueryResult<Integration[]>);
|
||||
|
||||
const { getByTestId } = render(<IntegrationsGuard>should be restricted</IntegrationsGuard>, {
|
||||
wrapper: TestProvidersComponent,
|
||||
});
|
||||
const { getByTestId } = render(
|
||||
<IntegrationsGuard>{'should be restricted'}</IntegrationsGuard>,
|
||||
{
|
||||
wrapper: TestProvidersComponent,
|
||||
}
|
||||
);
|
||||
|
||||
expect(getByTestId(LOADING_LOGO_TEST_ID)).toBeInTheDocument();
|
||||
expect(getByTestId(EMPTY_PAGE_SECURITY_TEMPLATE)).toBeInTheDocument();
|
||||
|
@ -95,9 +103,12 @@ describe('IntegrationsGuard', () => {
|
|||
data: [],
|
||||
} as unknown as UseQueryResult<Integration[]>);
|
||||
|
||||
const { getByTestId } = render(<IntegrationsGuard>should be restricted</IntegrationsGuard>, {
|
||||
wrapper: TestProvidersComponent,
|
||||
});
|
||||
const { getByTestId } = render(
|
||||
<IntegrationsGuard>{'should be restricted'}</IntegrationsGuard>,
|
||||
{
|
||||
wrapper: TestProvidersComponent,
|
||||
}
|
||||
);
|
||||
|
||||
expect(getByTestId(LOADING_LOGO_TEST_ID)).toBeInTheDocument();
|
||||
expect(getByTestId(EMPTY_PAGE_SECURITY_TEMPLATE)).toBeInTheDocument();
|
||||
|
@ -121,9 +132,12 @@ describe('IntegrationsGuard', () => {
|
|||
data: [],
|
||||
} as unknown as UseQueryResult<Integration[]>);
|
||||
|
||||
const { getByTestId } = render(<IntegrationsGuard>should be restricted</IntegrationsGuard>, {
|
||||
wrapper: TestProvidersComponent,
|
||||
});
|
||||
const { getByTestId } = render(
|
||||
<IntegrationsGuard>{'should be restricted'}</IntegrationsGuard>,
|
||||
{
|
||||
wrapper: TestProvidersComponent,
|
||||
}
|
||||
);
|
||||
expect(getByTestId(EMPTY_PROMPT_TEST_ID)).toBeInTheDocument();
|
||||
expect(getByTestId(EMPTY_PAGE_SECURITY_TEMPLATE)).toBeInTheDocument();
|
||||
});
|
||||
|
@ -140,7 +154,7 @@ describe('IntegrationsGuard', () => {
|
|||
data: [],
|
||||
} as unknown as UseQueryResult<Integration[]>);
|
||||
|
||||
const { asFragment } = render(<IntegrationsGuard>should be restricted</IntegrationsGuard>, {
|
||||
const { asFragment } = render(<IntegrationsGuard>{'should be restricted'}</IntegrationsGuard>, {
|
||||
wrapper: TestProvidersComponent,
|
||||
});
|
||||
expect(asFragment()).toMatchInlineSnapshot(`
|
||||
|
@ -168,7 +182,7 @@ describe('IntegrationsGuard', () => {
|
|||
],
|
||||
} as unknown as UseQueryResult<Integration[]>);
|
||||
|
||||
const { asFragment } = render(<IntegrationsGuard>should be restricted</IntegrationsGuard>, {
|
||||
const { asFragment } = render(<IntegrationsGuard>{'should be restricted'}</IntegrationsGuard>, {
|
||||
wrapper: TestProvidersComponent,
|
||||
});
|
||||
expect(asFragment()).toMatchInlineSnapshot(`
|
|
@ -6,7 +6,8 @@
|
|||
*/
|
||||
|
||||
import { EuiLoadingLogo, EuiPageTemplate } from '@elastic/eui';
|
||||
import React, { memo, PropsWithChildren } from 'react';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
import React, { memo } from 'react';
|
||||
import { LOADING_LOGO_TEST_ID } from './test_ids';
|
||||
import { useIntegrations } from '../hooks/use_integrations';
|
||||
import { EmptyPage } from '../modules/empty_page/empty_page';
|
||||
|
@ -44,3 +45,5 @@ export const IntegrationsGuard = memo<PropsWithChildren<unknown>>(({ children })
|
|||
const showIndicatorsPage = indicatorsTotalCount > 0 || (installedTIIntegrations || []).length > 0;
|
||||
return showIndicatorsPage ? <>{children}</> : <EmptyPage />;
|
||||
});
|
||||
|
||||
IntegrationsGuard.displayName = 'IntegrationsGuard';
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { FC, PropsWithChildren } from 'react';
|
||||
import React, { type FC, type PropsWithChildren } from 'react';
|
||||
import { useSecurityContext } from '../hooks/use_security_context';
|
||||
|
||||
/**
|
|
@ -5,8 +5,6 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
preset: '@kbn/test',
|
||||
rootDir: '../../../../../',
|
||||
roots: ['<rootDir>/x-pack/solutions/security/plugins/threat_intelligence'],
|
||||
};
|
||||
import { SecuritySolutionTemplateWrapper } from '../../app/home/template_wrapper';
|
||||
|
||||
export const SecuritySolutionPluginTemplateWrapper = SecuritySolutionTemplateWrapper;
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
const returnValue = {
|
||||
licenseService: { isEnterprise: jest.fn().mockReturnValue(false) },
|
||||
sourcererDataView: { id: 'security-solution-default' },
|
||||
};
|
||||
|
||||
export const useSecurityContext = () => returnValue;
|
|
@ -8,7 +8,7 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export const INSPECTOR_FLYOUT_TITLE = i18n.translate(
|
||||
'xpack.threatIntelligence.inspectorFlyoutTitle',
|
||||
'xpack.securitySolution.threatIntelligence.inspectorFlyoutTitle',
|
||||
{
|
||||
defaultMessage: 'Indicators search requests',
|
||||
}
|
|
@ -5,8 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { DocLinks } from '@kbn/doc-links';
|
||||
import { useKibana } from './use_kibana';
|
||||
import type { DocLinks } from '@kbn/doc-links';
|
||||
import { useKibana } from '../../common/lib/kibana';
|
||||
|
||||
const useKibanaDocumentationLinks = (): DocLinks => useKibana().services.docLinks.links;
|
||||
|
|
@ -6,8 +6,8 @@
|
|||
*/
|
||||
|
||||
import { useCallback, useContext, useEffect, useState } from 'react';
|
||||
import { InspectorSession } from '@kbn/inspector-plugin/public';
|
||||
import { useKibana } from './use_kibana';
|
||||
import type { InspectorSession } from '@kbn/inspector-plugin/public';
|
||||
import { useKibana } from '../../common/lib/kibana';
|
||||
import { InspectorContext } from '../containers/inspector';
|
||||
import { INSPECTOR_FLYOUT_TITLE } from './translations';
|
||||
|
|
@ -5,19 +5,21 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { FC, PropsWithChildren } from 'react';
|
||||
import React from 'react';
|
||||
import { waitFor, renderHook } from '@testing-library/react';
|
||||
import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query';
|
||||
import { INSTALLATION_STATUS, THREAT_INTELLIGENCE_CATEGORY } from '../utils/filter_integrations';
|
||||
|
||||
const createWrapper = () => {
|
||||
const createWrapper = (): FC<PropsWithChildren<{}>> => {
|
||||
const queryClient = new QueryClient();
|
||||
return ({ children }: { children: any }) => (
|
||||
// eslint-disable-next-line react/display-name
|
||||
return ({ children }) => (
|
||||
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const renderUseQuery = (result: { items: any[] }) =>
|
||||
const renderUseQuery = (result: { items: unknown[] }) =>
|
||||
renderHook(() => useQuery(['integrations'], () => result), {
|
||||
wrapper: createWrapper(),
|
||||
});
|
|
@ -5,10 +5,10 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { QueryFunctionContext, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { type QueryFunctionContext, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { useCallback, useEffect, useRef } from 'react';
|
||||
import { filterIntegrations } from '../utils/filter_integrations';
|
||||
import { useKibana } from './use_kibana';
|
||||
import { useKibana } from '../../common/lib/kibana';
|
||||
|
||||
type IntegrationInstallStatus = 'installed' | 'installing' | 'install_failed';
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { useKibana } from './use_kibana';
|
||||
import { useKibana } from '../../common/lib/kibana';
|
||||
|
||||
const useKibanaBasePath = (): string => useKibana().services.http.basePath.get();
|
||||
|
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
* 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 { useCallback } from 'react';
|
||||
|
||||
import moment from 'moment';
|
||||
import type { DataProvider } from '@kbn/timelines-plugin/common';
|
||||
import { generateDataProvider } from '../modules/timeline/utils/data_provider';
|
||||
import {
|
||||
fieldAndValueValid,
|
||||
getIndicatorFieldAndValue,
|
||||
} from '../modules/indicators/utils/field_value';
|
||||
import { unwrapValue } from '../modules/indicators/utils/unwrap_value';
|
||||
import {
|
||||
type Indicator,
|
||||
IndicatorFieldEventEnrichmentMap,
|
||||
RawIndicatorFieldId,
|
||||
} from '../../../common/threat_intelligence/types/indicator';
|
||||
import { timelineDefaults } from '../../timelines/store/defaults';
|
||||
import { APP_UI_ID } from '../../../common/constants';
|
||||
import { TimelineId } from '../../../common/types/timeline';
|
||||
import { TimelineTypeEnum } from '../../../common/api/timeline';
|
||||
import { useStartTransaction } from '../../common/lib/apm/use_start_transaction';
|
||||
import { useCreateTimeline } from '../../timelines/hooks/use_create_timeline';
|
||||
import type { CreateTimelineProps } from '../../detections/components/alerts_table/types';
|
||||
import { useUpdateTimeline } from '../../timelines/components/open_timeline/use_update_timeline';
|
||||
|
||||
interface UseInvestigateInTimelineActionProps {
|
||||
/**
|
||||
* Created when the user clicks on the Investigate in Timeline button.
|
||||
* DataProvider contain the field(s) and value(s) displayed in the timeline.
|
||||
*/
|
||||
dataProviders: DataProvider[];
|
||||
/**
|
||||
* Start date used in the createTimeline method.
|
||||
*/
|
||||
from: string;
|
||||
/**
|
||||
* End date used in the createTimeline method.
|
||||
*/
|
||||
to: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* This code is closely duplicated from here: https://github.com/elastic/kibana/blob/main/x-pack/solutions/security/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_investigate_in_timeline.tsx,
|
||||
* the main changes being:
|
||||
* - no exceptions are handled at the moment
|
||||
* - we use dataProviders, from and to directly instead of consuming ecsData
|
||||
*/
|
||||
const useInvestigateInTimelineInternal = ({
|
||||
dataProviders,
|
||||
from,
|
||||
to,
|
||||
}: UseInvestigateInTimelineActionProps) => {
|
||||
const { startTransaction } = useStartTransaction();
|
||||
|
||||
const clearActiveTimeline = useCreateTimeline({
|
||||
timelineId: TimelineId.active,
|
||||
timelineType: TimelineTypeEnum.default,
|
||||
});
|
||||
|
||||
const updateTimeline = useUpdateTimeline();
|
||||
|
||||
const createTimeline = useCallback(
|
||||
async ({ from: fromTimeline, timeline, to: toTimeline, ruleNote }: CreateTimelineProps) => {
|
||||
await clearActiveTimeline();
|
||||
updateTimeline({
|
||||
duplicate: true,
|
||||
from: fromTimeline,
|
||||
id: TimelineId.active,
|
||||
notes: [],
|
||||
timeline: {
|
||||
...timeline,
|
||||
indexNames: timeline.indexNames ?? [],
|
||||
show: true,
|
||||
},
|
||||
to: toTimeline,
|
||||
ruleNote,
|
||||
});
|
||||
},
|
||||
[updateTimeline, clearActiveTimeline]
|
||||
);
|
||||
|
||||
const investigateInTimelineClick = useCallback(async () => {
|
||||
startTransaction({ name: `${APP_UI_ID} threat indicator investigateInTimeline` });
|
||||
createTimeline({
|
||||
from,
|
||||
notes: null,
|
||||
timeline: {
|
||||
...timelineDefaults,
|
||||
dataProviders,
|
||||
id: TimelineId.active,
|
||||
indexNames: [],
|
||||
dateRange: {
|
||||
start: from,
|
||||
end: to,
|
||||
},
|
||||
eventType: 'all',
|
||||
filters: [],
|
||||
kqlQuery: {
|
||||
filterQuery: {
|
||||
kuery: {
|
||||
kind: 'kuery',
|
||||
expression: '',
|
||||
},
|
||||
serializedQuery: '',
|
||||
},
|
||||
},
|
||||
},
|
||||
to,
|
||||
ruleNote: '',
|
||||
});
|
||||
}, [startTransaction, createTimeline, dataProviders, from, to]);
|
||||
|
||||
return investigateInTimelineClick;
|
||||
};
|
||||
|
||||
export interface UseInvestigateInTimelineParam {
|
||||
/**
|
||||
* Indicator used to retrieve the field and value then passed to the Investigate in Timeline logic
|
||||
*/
|
||||
indicator: Indicator;
|
||||
}
|
||||
|
||||
export interface UseInvestigateInTimelineValue {
|
||||
/**
|
||||
* Investigate in Timeline function to run on click event.
|
||||
*/
|
||||
investigateInTimelineFn: () => Promise<void> | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom hook that gets an {@link Indicator}, retrieves the field (from the RawIndicatorFieldId.Name)
|
||||
* and value, then creates DataProviders used to do the Investigate in Timeline logic
|
||||
* (see /kibana/x-pack/solutions/security/plugins/security_solution/public/threat_intelligence/use_investigate_in_timeline.ts)
|
||||
*/
|
||||
export const useInvestigateInTimeline = ({
|
||||
indicator,
|
||||
}: UseInvestigateInTimelineParam): UseInvestigateInTimelineValue => {
|
||||
const { key, value } = getIndicatorFieldAndValue(indicator, RawIndicatorFieldId.Name);
|
||||
const sourceEventField = IndicatorFieldEventEnrichmentMap[key] ?? [];
|
||||
|
||||
const dataProviders: DataProvider[] = [...sourceEventField, key].map((e: string) =>
|
||||
generateDataProvider(e, value as string)
|
||||
);
|
||||
|
||||
const indicatorTimestamp: string = unwrapValue(
|
||||
indicator,
|
||||
RawIndicatorFieldId.TimeStamp
|
||||
) as string;
|
||||
|
||||
const from = moment(indicatorTimestamp).subtract(7, 'd').toISOString();
|
||||
const to = moment(indicatorTimestamp).add(7, 'd').toISOString();
|
||||
|
||||
const investigateInTimelineFn = useInvestigateInTimelineInternal({
|
||||
dataProviders,
|
||||
from,
|
||||
to,
|
||||
});
|
||||
|
||||
if (!to || !from) {
|
||||
return {} as unknown as UseInvestigateInTimelineValue;
|
||||
}
|
||||
|
||||
if (!fieldAndValueValid(key, value) || !sourceEventField) {
|
||||
return {} as unknown as UseInvestigateInTimelineValue;
|
||||
}
|
||||
|
||||
return { investigateInTimelineFn };
|
||||
};
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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 { useMemo } from 'react';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
|
||||
import type { SecuritySolutionPluginContext } from '../types';
|
||||
import { useKibana } from '../../common/lib/kibana';
|
||||
import { useUserPrivileges } from '../../common/components/user_privileges';
|
||||
import { useSetUrlParams } from '../../management/components/artifact_list_page/hooks/use_set_url_params';
|
||||
import { BlockListForm } from '../../management/pages/blocklist/view/components/blocklist_form';
|
||||
import { BlocklistsApiClient } from '../../management/pages/blocklist/services';
|
||||
import { inputsSelectors } from '../../common/store';
|
||||
import { licenseService } from '../../common/hooks/use_license';
|
||||
import { SecuritySolutionPageWrapper } from '../../common/components/page_wrapper';
|
||||
import { useGlobalTime } from '../../common/containers/use_global_time';
|
||||
import { deleteOneQuery, setQuery } from '../../common/store/inputs/actions';
|
||||
import { InputsModelId } from '../../common/store/inputs/constants';
|
||||
import { ArtifactFlyout } from '../../management/components/artifact_list_page/components/artifact_flyout';
|
||||
import { extractTimelineCapabilities } from '../../common/utils/timeline_capabilities';
|
||||
|
||||
export const useSecurityContext = (): SecuritySolutionPluginContext => {
|
||||
const {
|
||||
http,
|
||||
application: { capabilities },
|
||||
} = useKibana().services;
|
||||
|
||||
const { read: hasAccessToTimeline } = extractTimelineCapabilities(capabilities);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const canWriteBlocklist = useUserPrivileges().endpointPrivileges.canWriteBlocklist;
|
||||
|
||||
return useMemo(() => {
|
||||
return {
|
||||
getPageWrapper: () => SecuritySolutionPageWrapper,
|
||||
licenseService,
|
||||
hasAccessToTimeline,
|
||||
|
||||
blockList: {
|
||||
canWriteBlocklist,
|
||||
exceptionListApiClient: BlocklistsApiClient.getInstance(http),
|
||||
useSetUrlParams,
|
||||
// @ts-ignore
|
||||
getFlyoutComponent: () => ArtifactFlyout,
|
||||
// @ts-ignore
|
||||
getFormComponent: () => BlockListForm,
|
||||
} as unknown as SecuritySolutionPluginContext['blockList'],
|
||||
|
||||
useQuery: () => useSelector(inputsSelectors.globalQuerySelector()),
|
||||
useFilters: () => useSelector(inputsSelectors.globalFiltersQuerySelector()),
|
||||
useGlobalTime,
|
||||
|
||||
registerQuery: (query) =>
|
||||
dispatch(
|
||||
setQuery({
|
||||
inputId: InputsModelId.global,
|
||||
id: query.id,
|
||||
refetch: query.refetch,
|
||||
inspect: null,
|
||||
loading: query.loading,
|
||||
})
|
||||
),
|
||||
deregisterQuery: (query) =>
|
||||
dispatch(
|
||||
deleteOneQuery({
|
||||
inputId: InputsModelId.global,
|
||||
id: query.id,
|
||||
})
|
||||
),
|
||||
};
|
||||
}, [hasAccessToTimeline, canWriteBlocklist, http, dispatch]);
|
||||
};
|
|
@ -5,15 +5,14 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { SecuritySubPlugin } from '../app/types';
|
||||
import { routes } from './routes';
|
||||
|
||||
export class ThreatIntelligence {
|
||||
public setup() {}
|
||||
|
||||
public start(): SecuritySubPlugin {
|
||||
public start() {
|
||||
return {
|
||||
routes,
|
||||
};
|
||||
}
|
||||
|
||||
public stop() {}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
preset: '@kbn/test',
|
||||
rootDir: '../../../../../../..',
|
||||
roots: [
|
||||
'<rootDir>/x-pack/solutions/security/plugins/security_solution/public/threat_intelligence',
|
||||
],
|
||||
coverageDirectory:
|
||||
'<rootDir>/target/kibana-coverage/jest/x-pack/solutions/security/plugins/security_solution/public/threat_intelligence',
|
||||
coverageReporters: ['text', 'html'],
|
||||
collectCoverageFrom: [
|
||||
'<rootDir>/x-pack/solutions/security/plugins/security_solution/public/threat_intelligence/**/*.{ts,tsx}',
|
||||
],
|
||||
moduleNameMapper: require('../../server/__mocks__/module_name_map'),
|
||||
};
|
|
@ -5,10 +5,10 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { getSecuritySolutionLink } from '@kbn/threat-intelligence-plugin/public';
|
||||
import type { SecurityPageName } from '../../common/constants';
|
||||
import { SECURITY_FEATURE_ID } from '../../common/constants';
|
||||
import type { LinkItem } from '../common/links';
|
||||
import { getSecuritySolutionLink } from './utils/security_solution_links';
|
||||
|
||||
/**
|
||||
* Adds the Threat Intelligence entry to Kibana global sidenav as well as the Security sidenav.
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { FieldTypesContextValue } from '../containers/field_types_provider';
|
||||
import type { FieldTypesContextValue } from '../containers/field_types_provider';
|
||||
|
||||
/**
|
||||
* Mock to map an indicator field to its type.
|
|
@ -5,8 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { FilterManager } from '@kbn/data-plugin/public';
|
||||
import { IndicatorsFiltersContextValue } from '../modules/indicators/hooks/use_filters_context';
|
||||
import type { FilterManager } from '@kbn/data-plugin/public';
|
||||
import type { IndicatorsFiltersContextValue } from '../modules/indicators/hooks/use_filters_context';
|
||||
|
||||
export const mockTimeRange = { from: '2022-10-03T07:48:31.498Z', to: '2022-10-03T07:48:31.498Z' };
|
||||
|
|
@ -6,9 +6,9 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { HoverActionsConfig } from '@kbn/timelines-plugin/public/components/hover_actions';
|
||||
import type { HoverActionsConfig } from '@kbn/timelines-plugin/public/components/hover_actions';
|
||||
import { EuiButtonIcon } from '@elastic/eui';
|
||||
import { TimelinesUIStart } from '@kbn/timelines-plugin/public';
|
||||
import type { TimelinesUIStart } from '@kbn/timelines-plugin/public';
|
||||
|
||||
/**
|
||||
* Returns a default object to mock the timelines plugin for our unit tests and storybook stories.
|
|
@ -7,15 +7,16 @@
|
|||
|
||||
import React from 'react';
|
||||
import { EuiText } from '@elastic/eui';
|
||||
import { TriggersAndActionsUIPublicPluginStart as TriggersActionsStart } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import type { TriggersAndActionsUIPublicPluginStart as TriggersActionsStart } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
|
||||
const styles = { display: 'inline' };
|
||||
/**
|
||||
* Returns a default object to mock the triggers actions ui plugin for our unit tests and storybook stories.
|
||||
*/
|
||||
export const mockTriggersActionsUiService: TriggersActionsStart = {
|
||||
getFieldBrowser: () => (
|
||||
<EuiText style={{ display: 'inline' }} size="xs">
|
||||
Fields
|
||||
<EuiText css={styles} size="xs">
|
||||
{'Fields'}
|
||||
</EuiText>
|
||||
),
|
||||
} as unknown as TriggersActionsStart;
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { IUiSettingsClient } from '@kbn/core/public';
|
||||
import type { IUiSettingsClient } from '@kbn/core/public';
|
||||
import { DEFAULT_DATE_FORMAT, DEFAULT_DATE_FORMAT_TZ } from '../constants/common';
|
||||
|
||||
/**
|
|
@ -5,15 +5,16 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { Filter } from '@kbn/es-query';
|
||||
import type { Filter } from '@kbn/es-query';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import * as hook from '../hooks/use_kibana';
|
||||
import * as hook from '../../common/lib/kibana';
|
||||
|
||||
jest.mock('../hooks/use_kibana');
|
||||
jest.mock('../../common/lib/kibana');
|
||||
|
||||
interface MockConfig {
|
||||
$filterUpdates?: BehaviorSubject<void>;
|
||||
getFilters?: jest.Mock<Filter[]>;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
setFilters?: jest.Mock<any, Filter[]>;
|
||||
}
|
||||
|
||||
|
@ -43,6 +44,7 @@ export const mockUseKibanaForFilters = ({
|
|||
},
|
||||
dataViews: { getFieldsForWildcard },
|
||||
},
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} as any);
|
||||
|
||||
return { getFieldsForWildcard, setFilters, getFilters, $filterUpdates };
|
|
@ -5,18 +5,17 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { FC, ReactNode, VFC } from 'react';
|
||||
import type { ReactNode, FC } from 'react';
|
||||
import React from 'react';
|
||||
import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public';
|
||||
import { DataPublicPluginStart } from '@kbn/data-plugin/public';
|
||||
import { CoreStart, IUiSettingsClient } from '@kbn/core/public';
|
||||
import { TimelinesUIStart } from '@kbn/timelines-plugin/public';
|
||||
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
|
||||
import type { CoreStart, IUiSettingsClient } from '@kbn/core/public';
|
||||
import type { TimelinesUIStart } from '@kbn/timelines-plugin/public';
|
||||
import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common';
|
||||
import { RequestAdapter } from '@kbn/inspector-plugin/common';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import type { SettingsStart } from '@kbn/core-ui-settings-browser';
|
||||
import { mockIndicatorsFiltersContext } from './mock_indicators_filters_context';
|
||||
import { SecuritySolutionContext } from '../containers/security_solution_context';
|
||||
import { getSecuritySolutionContextMock } from './mock_security_context';
|
||||
import { IndicatorsFiltersContext } from '../modules/indicators/hooks/use_filters_context';
|
||||
import { FieldTypesContext } from '../containers/field_types_provider';
|
||||
import { generateFieldTypeMap } from './mock_field_type_map';
|
||||
|
@ -57,6 +56,7 @@ export interface StoryProvidersComponentProps {
|
|||
const securityLayout = {
|
||||
getPluginWrapper:
|
||||
(): FC =>
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
({ children, isEmptyState, emptyPageBody }: any) => {
|
||||
if (isEmptyState && emptyPageBody) {
|
||||
return <>{emptyPageBody}</>;
|
||||
|
@ -92,7 +92,7 @@ const defaultServices = {
|
|||
* Helper functional component used in Storybook stories.
|
||||
* Wraps the story with our {@link SecuritySolutionContext} and KibanaReactContext.
|
||||
*/
|
||||
export const StoryProvidersComponent: VFC<StoryProvidersComponentProps> = ({
|
||||
export const StoryProvidersComponent: FC<StoryProvidersComponentProps> = ({
|
||||
children,
|
||||
kibana = {},
|
||||
}) => {
|
||||
|
@ -101,20 +101,16 @@ export const StoryProvidersComponent: VFC<StoryProvidersComponentProps> = ({
|
|||
...kibana,
|
||||
securityLayout,
|
||||
});
|
||||
const securitySolutionContextMock = getSecuritySolutionContextMock();
|
||||
|
||||
return (
|
||||
<EuiThemeProvider>
|
||||
<QueryClientProvider client={new QueryClient()}>
|
||||
<InspectorContext.Provider value={{ requests: new RequestAdapter() }}>
|
||||
<FieldTypesContext.Provider value={generateFieldTypeMap()}>
|
||||
<SecuritySolutionContext.Provider value={securitySolutionContextMock}>
|
||||
<IndicatorsFiltersContext.Provider value={mockIndicatorsFiltersContext}>
|
||||
<KibanaReactContext.Provider>
|
||||
<BlockListProvider>{children}</BlockListProvider>
|
||||
</KibanaReactContext.Provider>
|
||||
</IndicatorsFiltersContext.Provider>
|
||||
</SecuritySolutionContext.Provider>
|
||||
<IndicatorsFiltersContext.Provider value={mockIndicatorsFiltersContext}>
|
||||
<KibanaReactContext.Provider>
|
||||
<BlockListProvider>{children}</BlockListProvider>
|
||||
</KibanaReactContext.Provider>
|
||||
</IndicatorsFiltersContext.Provider>
|
||||
</FieldTypesContext.Provider>
|
||||
</InspectorContext.Provider>
|
||||
</QueryClientProvider>
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* 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 type { FC, PropsWithChildren } from 'react';
|
||||
import React from 'react';
|
||||
import type { IStorage } from '@kbn/kibana-utils-plugin/public';
|
||||
import { Storage } from '@kbn/kibana-utils-plugin/public';
|
||||
import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks';
|
||||
import { RequestAdapter } from '@kbn/inspector-plugin/common';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import type { ISearchStart } from '@kbn/data-plugin/public';
|
||||
import moment from 'moment';
|
||||
import { IndicatorsFiltersContext } from '../modules/indicators/hooks/use_filters_context';
|
||||
import { mockIndicatorsFiltersContext } from './mock_indicators_filters_context';
|
||||
import { FieldTypesContext } from '../containers/field_types_provider';
|
||||
import { generateFieldTypeMap } from './mock_field_type_map';
|
||||
import { InspectorContext } from '../containers/inspector';
|
||||
import { TestProviders } from '../../common/mock/test_providers';
|
||||
|
||||
export const localStorageMock = (): IStorage => {
|
||||
let store: Record<string, unknown> = {};
|
||||
|
||||
return {
|
||||
getItem: (key: string) => {
|
||||
return store[key] || null;
|
||||
},
|
||||
setItem: (key: string, value: unknown) => {
|
||||
store[key] = value;
|
||||
},
|
||||
clear() {
|
||||
store = {};
|
||||
},
|
||||
removeItem(key: string) {
|
||||
delete store[key];
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const mockedSearchService = {
|
||||
search: jest.fn(),
|
||||
showError: jest.fn(),
|
||||
} as unknown as ISearchStart;
|
||||
|
||||
const fixedMoment = moment(new Date('2025-05-16 00:00:00'));
|
||||
|
||||
export const mockedTimefilterService = {
|
||||
timefilter: {
|
||||
calculateBounds: jest.fn().mockReturnValue({ min: fixedMoment, max: fixedMoment }),
|
||||
},
|
||||
};
|
||||
|
||||
export const mockedQueryService = {
|
||||
timefilter: mockedTimefilterService,
|
||||
};
|
||||
|
||||
export const createTiStorageMock = () => {
|
||||
const localStorage = localStorageMock();
|
||||
return {
|
||||
localStorage,
|
||||
storage: new Storage(localStorage),
|
||||
};
|
||||
};
|
||||
|
||||
export const mockedServices = {
|
||||
...createTiStorageMock(),
|
||||
};
|
||||
|
||||
export const unifiedSearch = unifiedSearchPluginMock.createStartContract();
|
||||
|
||||
export const EMPTY_PAGE_SECURITY_TEMPLATE = 'empty-page-security-template' as const;
|
||||
|
||||
export const TestProvidersComponent: FC<PropsWithChildren<{}>> = ({ children }) => (
|
||||
<TestProviders>
|
||||
<MemoryRouter>
|
||||
<InspectorContext.Provider value={{ requests: new RequestAdapter() }}>
|
||||
<QueryClientProvider client={new QueryClient()}>
|
||||
<FieldTypesContext.Provider value={generateFieldTypeMap()}>
|
||||
<IndicatorsFiltersContext.Provider value={mockIndicatorsFiltersContext}>
|
||||
{children}
|
||||
</IndicatorsFiltersContext.Provider>
|
||||
</FieldTypesContext.Provider>
|
||||
</QueryClientProvider>
|
||||
</InspectorContext.Provider>
|
||||
</MemoryRouter>
|
||||
</TestProviders>
|
||||
);
|
|
@ -8,9 +8,6 @@
|
|||
import React from 'react';
|
||||
import type { StoryFn } from '@storybook/react';
|
||||
import { EuiContextMenuPanel } from '@elastic/eui';
|
||||
import { SecuritySolutionContext } from '../../../containers/security_solution_context';
|
||||
import { SecuritySolutionPluginContext } from '../../..';
|
||||
import { getSecuritySolutionContextMock } from '../../../mocks/mock_security_context';
|
||||
import { AddToBlockListContextMenu } from './add_to_block_list';
|
||||
import { BlockListProvider } from '../../indicators/containers/block_list_provider';
|
||||
|
||||
|
@ -19,8 +16,6 @@ export default {
|
|||
};
|
||||
|
||||
export const ContextMenu: StoryFn = () => {
|
||||
const mockSecurityContext: SecuritySolutionPluginContext = getSecuritySolutionContextMock();
|
||||
|
||||
const mockIndicatorFileHashValue: string = 'abc';
|
||||
const mockOnClick: () => void = () => window.alert('clicked!');
|
||||
const items = [
|
||||
|
@ -28,18 +23,13 @@ export const ContextMenu: StoryFn = () => {
|
|||
];
|
||||
|
||||
return (
|
||||
<SecuritySolutionContext.Provider value={mockSecurityContext}>
|
||||
<BlockListProvider>
|
||||
<EuiContextMenuPanel items={items} />
|
||||
</BlockListProvider>
|
||||
</SecuritySolutionContext.Provider>
|
||||
<BlockListProvider>
|
||||
<EuiContextMenuPanel items={items} />
|
||||
</BlockListProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export const Disabled: StoryFn = () => {
|
||||
const mockSecurityContext: SecuritySolutionPluginContext = getSecuritySolutionContextMock();
|
||||
mockSecurityContext.blockList.canWriteBlocklist = false;
|
||||
|
||||
const mockIndicatorFileHashValue: string = 'abc';
|
||||
const mockOnClick: () => void = () => window.alert('clicked!');
|
||||
const items = [
|
||||
|
@ -47,10 +37,8 @@ export const Disabled: StoryFn = () => {
|
|||
];
|
||||
|
||||
return (
|
||||
<SecuritySolutionContext.Provider value={mockSecurityContext}>
|
||||
<BlockListProvider>
|
||||
<EuiContextMenuPanel items={items} />
|
||||
</BlockListProvider>
|
||||
</SecuritySolutionContext.Provider>
|
||||
<BlockListProvider>
|
||||
<EuiContextMenuPanel items={items} />
|
||||
</BlockListProvider>
|
||||
);
|
||||
};
|
|
@ -9,22 +9,18 @@ import React from 'react';
|
|||
import { render } from '@testing-library/react';
|
||||
import { AddToBlockListContextMenu } from './add_to_block_list';
|
||||
import { BlockListProvider } from '../../indicators/containers/block_list_provider';
|
||||
import { SecuritySolutionContext } from '../../../containers/security_solution_context';
|
||||
import { SecuritySolutionPluginContext } from '../../..';
|
||||
import { getSecuritySolutionContextMock } from '../../../mocks/mock_security_context';
|
||||
import { I18nProvider } from '@kbn/i18n-react';
|
||||
import { TestProvidersComponent } from '../../../mocks/test_providers';
|
||||
const TEST_ID = 'test';
|
||||
|
||||
describe('<AddToBlockListContextMenu />', () => {
|
||||
it('should render an EuiContextMenuItem', () => {
|
||||
const mockSecurityContext: SecuritySolutionPluginContext = getSecuritySolutionContextMock();
|
||||
|
||||
const mockIndicatorFileHashValue: string = 'abc';
|
||||
const mockOnClick: () => void = () => window.alert('clicked!');
|
||||
|
||||
const { getByTestId, getAllByText } = render(
|
||||
<I18nProvider>
|
||||
<SecuritySolutionContext.Provider value={mockSecurityContext}>
|
||||
<TestProvidersComponent>
|
||||
<I18nProvider>
|
||||
<BlockListProvider>
|
||||
<AddToBlockListContextMenu
|
||||
data={mockIndicatorFileHashValue}
|
||||
|
@ -32,8 +28,8 @@ describe('<AddToBlockListContextMenu />', () => {
|
|||
data-test-subj={TEST_ID}
|
||||
/>
|
||||
</BlockListProvider>
|
||||
</SecuritySolutionContext.Provider>
|
||||
</I18nProvider>
|
||||
</I18nProvider>
|
||||
</TestProvidersComponent>
|
||||
);
|
||||
|
||||
expect(getByTestId(TEST_ID)).toBeInTheDocument();
|
||||
|
@ -41,14 +37,12 @@ describe('<AddToBlockListContextMenu />', () => {
|
|||
});
|
||||
|
||||
it('should render a disabled EuiContextMenuItem if data is null', () => {
|
||||
const mockSecurityContext: SecuritySolutionPluginContext = getSecuritySolutionContextMock();
|
||||
|
||||
const mockIndicatorFileHashValue = null;
|
||||
const mockOnClick: () => void = () => window.alert('clicked!');
|
||||
|
||||
const { getByTestId } = render(
|
||||
<I18nProvider>
|
||||
<SecuritySolutionContext.Provider value={mockSecurityContext}>
|
||||
<TestProvidersComponent>
|
||||
<I18nProvider>
|
||||
<BlockListProvider>
|
||||
<AddToBlockListContextMenu
|
||||
data={mockIndicatorFileHashValue}
|
||||
|
@ -56,23 +50,20 @@ describe('<AddToBlockListContextMenu />', () => {
|
|||
data-test-subj={TEST_ID}
|
||||
/>
|
||||
</BlockListProvider>
|
||||
</SecuritySolutionContext.Provider>
|
||||
</I18nProvider>
|
||||
</I18nProvider>
|
||||
</TestProvidersComponent>
|
||||
);
|
||||
|
||||
expect(getByTestId(TEST_ID)).toHaveAttribute('disabled');
|
||||
});
|
||||
|
||||
it('should render a disabled EuiContextMenuItem if no write blocklist privilege', () => {
|
||||
const mockSecurityContext: SecuritySolutionPluginContext = getSecuritySolutionContextMock();
|
||||
mockSecurityContext.blockList.canWriteBlocklist = false;
|
||||
|
||||
const mockIndicatorFileHashValue: string = 'abc';
|
||||
const mockOnClick: () => void = () => window.alert('clicked!');
|
||||
|
||||
const { getByTestId } = render(
|
||||
<I18nProvider>
|
||||
<SecuritySolutionContext.Provider value={mockSecurityContext}>
|
||||
<TestProvidersComponent>
|
||||
<I18nProvider>
|
||||
<BlockListProvider>
|
||||
<AddToBlockListContextMenu
|
||||
data={mockIndicatorFileHashValue}
|
||||
|
@ -80,8 +71,8 @@ describe('<AddToBlockListContextMenu />', () => {
|
|||
data-test-subj={TEST_ID}
|
||||
/>
|
||||
</BlockListProvider>
|
||||
</SecuritySolutionContext.Provider>
|
||||
</I18nProvider>
|
||||
</I18nProvider>
|
||||
</TestProvidersComponent>
|
||||
);
|
||||
|
||||
expect(getByTestId(TEST_ID)).toHaveAttribute('disabled');
|
|
@ -5,7 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { VFC } from 'react';
|
||||
import type { FC } from 'react';
|
||||
import React from 'react';
|
||||
import { EuiContextMenuItem } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { useSecurityContext } from '../../../hooks/use_security_context';
|
||||
|
@ -33,7 +34,7 @@ export interface AddToBlockListProps {
|
|||
* When clicking on the ContextMenuItem, the indicator filehash value is saved in context.
|
||||
* The flyout is shown by adding a parameter to the url.
|
||||
*/
|
||||
export const AddToBlockListContextMenu: VFC<AddToBlockListProps> = ({
|
||||
export const AddToBlockListContextMenu: FC<AddToBlockListProps> = ({
|
||||
data,
|
||||
'data-test-subj': dataTestSub,
|
||||
onClick,
|
||||
|
@ -61,7 +62,7 @@ export const AddToBlockListContextMenu: VFC<AddToBlockListProps> = ({
|
|||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Add blocklist entry"
|
||||
id="xpack.threatIntelligence.addToBlockList"
|
||||
id="xpack.securitySolution.threatIntelligence.addToBlockList"
|
||||
/>
|
||||
</EuiContextMenuItem>
|
||||
);
|
|
@ -5,8 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { VFC } from 'react';
|
||||
import {
|
||||
import type { FC } from 'react';
|
||||
import React from 'react';
|
||||
import type {
|
||||
CreateExceptionListItemSchema,
|
||||
EntriesArray,
|
||||
} from '@kbn/securitysolution-io-ts-list-types';
|
||||
|
@ -28,7 +29,7 @@ export interface BlockListFlyoutProps {
|
|||
* - the flyout component: x-pack/solutions/security/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.tsx
|
||||
* - the form component: x-pack/solutions/security/plugins/security_solution/public/management/pages/blocklist/view/components/blocklist_form.tsx
|
||||
*/
|
||||
export const BlockListFlyout: VFC<BlockListFlyoutProps> = ({ indicatorFileHash }) => {
|
||||
export const BlockListFlyout: FC<BlockListFlyoutProps> = ({ indicatorFileHash }) => {
|
||||
const { setBlockListIndicatorValue } = useBlockListContext();
|
||||
const { blockList } = useSecurityContext();
|
||||
const Component = blockList.getFlyoutComponent();
|
|
@ -8,7 +8,7 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export const ADD_TO_BLOCKLIST_FLYOUT_TITLE = i18n.translate(
|
||||
'xpack.threatIntelligence.blocklist.flyoutTitle',
|
||||
'xpack.securitySolution.threatIntelligence.blocklist.flyoutTitle',
|
||||
{
|
||||
defaultMessage: 'Add blocklist',
|
||||
}
|
|
@ -11,11 +11,13 @@ import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-quer
|
|||
|
||||
const createWrapper = () => {
|
||||
const queryClient = new QueryClient();
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, react/display-name
|
||||
return ({ children }: { children: any }) => (
|
||||
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
||||
);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const renderUseQuery = (result: { items: any[] }) =>
|
||||
renderHook(() => useQuery(['policies'], () => result), {
|
||||
wrapper: createWrapper(),
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useKibana } from '../../../hooks/use_kibana';
|
||||
import { useKibana } from '../../../../common/lib/kibana';
|
||||
|
||||
const POLICIES_URL = '/api/fleet/package_policies';
|
||||
const PACKAGE_POLICY_SAVED_OBJECT_TYPE = 'ingest-package-policies';
|
|
@ -5,11 +5,11 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { Indicator } from '../../../../../common/threat_intelligence/types/indicator';
|
||||
import {
|
||||
generateMockFileIndicator,
|
||||
Indicator,
|
||||
RawIndicatorFieldId,
|
||||
} from '../../../../common/types/indicator';
|
||||
} from '../../../../../common/threat_intelligence/types/indicator';
|
||||
import { canAddToBlockList } from './can_add_to_block_list';
|
||||
import { getIndicatorFieldAndValue } from '../../indicators/utils/field_value';
|
||||
|
|
@ -5,7 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { Indicator, RawIndicatorFieldId } from '../../../../common/types/indicator';
|
||||
import type { Indicator } from '../../../../../common/threat_intelligence/types/indicator';
|
||||
import { RawIndicatorFieldId } from '../../../../../common/threat_intelligence/types/indicator';
|
||||
import { getIndicatorFieldAndValue } from '../../indicators/utils/field_value';
|
||||
|
||||
/**
|
|
@ -9,7 +9,7 @@ import React from 'react';
|
|||
import type { StoryFn } from '@storybook/react';
|
||||
import { EuiContextMenuPanel } from '@elastic/eui';
|
||||
import { StoryProvidersComponent } from '../../../mocks/story_providers';
|
||||
import { generateMockUrlIndicator } from '../../../../common/types/indicator';
|
||||
import { generateMockUrlIndicator } from '../../../../../common/threat_intelligence/types/indicator';
|
||||
import { AddToExistingCase } from './add_to_existing_case';
|
||||
|
||||
export default {
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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 React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { AddToExistingCase } from './add_to_existing_case';
|
||||
import { TestProvidersComponent } from '../../../mocks/test_providers';
|
||||
import {
|
||||
generateMockFileIndicator,
|
||||
type Indicator,
|
||||
} from '../../../../../common/threat_intelligence/types/indicator';
|
||||
|
||||
const TEST_ID = 'test';
|
||||
const indicator: Indicator = generateMockFileIndicator();
|
||||
const onClick = () => window.alert('clicked');
|
||||
|
||||
describe('AddToExistingCase', () => {
|
||||
it('should render an EuiContextMenuItem', () => {
|
||||
const { getByTestId, getAllByText } = render(
|
||||
<TestProvidersComponent>
|
||||
<AddToExistingCase indicator={indicator} onClick={onClick} data-test-subj={TEST_ID} />
|
||||
</TestProvidersComponent>
|
||||
);
|
||||
expect(getByTestId(TEST_ID)).toBeInTheDocument();
|
||||
expect(getAllByText('Add to existing case')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('should render the EuiContextMenuItem disabled if indicator is missing name', () => {
|
||||
const fields = { ...indicator.fields };
|
||||
delete fields['threat.indicator.name'];
|
||||
const indicatorMissingName = {
|
||||
_id: indicator._id,
|
||||
fields,
|
||||
};
|
||||
const { getByTestId } = render(
|
||||
<TestProvidersComponent>
|
||||
<AddToExistingCase
|
||||
indicator={indicatorMissingName}
|
||||
onClick={onClick}
|
||||
data-test-subj={TEST_ID}
|
||||
/>
|
||||
</TestProvidersComponent>
|
||||
);
|
||||
expect(getByTestId(TEST_ID)).toHaveAttribute('disabled');
|
||||
});
|
||||
|
||||
it('should render the EuiContextMenuItem disabled if user has no update permission', () => {
|
||||
const { getByTestId } = render(
|
||||
<TestProvidersComponent>
|
||||
<AddToExistingCase indicator={indicator} onClick={onClick} data-test-subj={TEST_ID} />
|
||||
</TestProvidersComponent>
|
||||
);
|
||||
expect(getByTestId(TEST_ID)).toHaveAttribute('disabled');
|
||||
});
|
||||
});
|
|
@ -5,18 +5,16 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { VFC } from 'react';
|
||||
import type { FC } from 'react';
|
||||
import React from 'react';
|
||||
import { EuiContextMenuItem } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { CaseAttachmentsWithoutOwner } from '@kbn/cases-plugin/public';
|
||||
import type { CaseAttachmentsWithoutOwner } from '@kbn/cases-plugin/public';
|
||||
import { useCaseDisabled } from '../hooks/use_case_permission';
|
||||
import {
|
||||
AttachmentMetadata,
|
||||
generateAttachmentsMetadata,
|
||||
generateAttachmentsWithoutOwner,
|
||||
} from '../utils/attachments';
|
||||
import { useKibana } from '../../../hooks/use_kibana';
|
||||
import { Indicator } from '../../../../common/types/indicator';
|
||||
import type { AttachmentMetadata } from '../utils/attachments';
|
||||
import { generateAttachmentsMetadata, generateAttachmentsWithoutOwner } from '../utils/attachments';
|
||||
import { useKibana } from '../../../../common/lib/kibana';
|
||||
import type { Indicator } from '../../../../../common/threat_intelligence/types/indicator';
|
||||
|
||||
export interface AddToExistingCaseProps {
|
||||
/**
|
||||
|
@ -42,7 +40,7 @@ export interface AddToExistingCaseProps {
|
|||
*
|
||||
* @returns add to existing case for a context menu
|
||||
*/
|
||||
export const AddToExistingCase: VFC<AddToExistingCaseProps> = ({
|
||||
export const AddToExistingCase: FC<AddToExistingCaseProps> = ({
|
||||
indicator,
|
||||
onClick,
|
||||
'data-test-subj': dataTestSubj,
|
||||
|
@ -73,7 +71,7 @@ export const AddToExistingCase: VFC<AddToExistingCaseProps> = ({
|
|||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Add to existing case"
|
||||
id="xpack.threatIntelligence.addToExistingCase"
|
||||
id="xpack.securitySolution.threatIntelligence.addToExistingCase"
|
||||
/>
|
||||
</EuiContextMenuItem>
|
||||
);
|
|
@ -10,7 +10,7 @@ import type { StoryFn } from '@storybook/react';
|
|||
import { EuiContextMenuPanel } from '@elastic/eui';
|
||||
import { AddToNewCase } from './add_to_new_case';
|
||||
import { StoryProvidersComponent } from '../../../mocks/story_providers';
|
||||
import { generateMockUrlIndicator } from '../../../../common/types/indicator';
|
||||
import { generateMockUrlIndicator } from '../../../../../common/threat_intelligence/types/indicator';
|
||||
|
||||
export default {
|
||||
title: 'AddToNewCase',
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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 { render } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import {
|
||||
generateMockFileIndicator,
|
||||
type Indicator,
|
||||
} from '../../../../../common/threat_intelligence/types/indicator';
|
||||
import { TestProvidersComponent } from '../../../mocks/test_providers';
|
||||
import { AddToNewCase } from './add_to_new_case';
|
||||
|
||||
const TEST_ID = 'test';
|
||||
const indicator: Indicator = generateMockFileIndicator();
|
||||
const onClick = () => window.alert('clicked');
|
||||
|
||||
describe('AddToNewCase', () => {
|
||||
it('should render an EuiContextMenuItem', () => {
|
||||
const { getByTestId, getAllByText } = render(
|
||||
<TestProvidersComponent>
|
||||
<AddToNewCase indicator={indicator} onClick={onClick} data-test-subj={TEST_ID} />
|
||||
</TestProvidersComponent>
|
||||
);
|
||||
expect(getByTestId(TEST_ID)).toBeInTheDocument();
|
||||
expect(getAllByText('Add to new case')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('should render the EuiContextMenuItem disabled if indicator is missing name', () => {
|
||||
const fields = { ...indicator.fields };
|
||||
delete fields['threat.indicator.name'];
|
||||
const indicatorMissingName = {
|
||||
_id: indicator._id,
|
||||
fields,
|
||||
};
|
||||
|
||||
const { getByTestId } = render(
|
||||
<TestProvidersComponent>
|
||||
<AddToNewCase indicator={indicatorMissingName} onClick={onClick} data-test-subj={TEST_ID} />
|
||||
</TestProvidersComponent>
|
||||
);
|
||||
expect(getByTestId(TEST_ID)).toHaveAttribute('disabled');
|
||||
});
|
||||
|
||||
it('should render the EuiContextMenuItem disabled if user have no create permission', () => {
|
||||
const { getByTestId } = render(
|
||||
<TestProvidersComponent>
|
||||
<AddToNewCase indicator={indicator} onClick={onClick} data-test-subj={TEST_ID} />
|
||||
</TestProvidersComponent>
|
||||
);
|
||||
expect(getByTestId(TEST_ID)).toHaveAttribute('disabled');
|
||||
});
|
||||
});
|
|
@ -5,18 +5,16 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { VFC } from 'react';
|
||||
import type { FC } from 'react';
|
||||
import React from 'react';
|
||||
import { EuiContextMenuItem } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { CaseAttachmentsWithoutOwner } from '@kbn/cases-plugin/public';
|
||||
import type { CaseAttachmentsWithoutOwner } from '@kbn/cases-plugin/public';
|
||||
import { useCaseDisabled } from '../hooks/use_case_permission';
|
||||
import {
|
||||
AttachmentMetadata,
|
||||
generateAttachmentsMetadata,
|
||||
generateAttachmentsWithoutOwner,
|
||||
} from '../utils/attachments';
|
||||
import { useKibana } from '../../../hooks/use_kibana';
|
||||
import { Indicator } from '../../../../common/types/indicator';
|
||||
import type { AttachmentMetadata } from '../utils/attachments';
|
||||
import { generateAttachmentsMetadata, generateAttachmentsWithoutOwner } from '../utils/attachments';
|
||||
import { useKibana } from '../../../../common/lib/kibana';
|
||||
import type { Indicator } from '../../../../../common/threat_intelligence/types/indicator';
|
||||
|
||||
export interface AddToNewCaseProps {
|
||||
/**
|
||||
|
@ -42,7 +40,7 @@ export interface AddToNewCaseProps {
|
|||
*
|
||||
* @returns add to existing case for a context menu
|
||||
*/
|
||||
export const AddToNewCase: VFC<AddToNewCaseProps> = ({
|
||||
export const AddToNewCase: FC<AddToNewCaseProps> = ({
|
||||
indicator,
|
||||
onClick,
|
||||
'data-test-subj': dataTestSubj,
|
||||
|
@ -73,7 +71,7 @@ export const AddToNewCase: VFC<AddToNewCaseProps> = ({
|
|||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Add to new case"
|
||||
id="xpack.threatIntelligence.addToNewCase"
|
||||
id="xpack.securitySolution.threatIntelligence.addToNewCase"
|
||||
/>
|
||||
</EuiContextMenuItem>
|
||||
);
|
|
@ -6,8 +6,8 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { ExternalReferenceAttachmentViewProps } from '@kbn/cases-plugin/public/client/attachment_framework/types';
|
||||
import { AttachmentMetadata } from '../utils/attachments';
|
||||
import type { ExternalReferenceAttachmentViewProps } from '@kbn/cases-plugin/public/client/attachment_framework/types';
|
||||
import type { AttachmentMetadata } from '../utils/attachments';
|
||||
import { CommentChildren } from './comment_children';
|
||||
|
||||
/**
|
||||
|
@ -17,6 +17,7 @@ import { CommentChildren } from './comment_children';
|
|||
* It renders some text and a flyout.
|
||||
*/
|
||||
export const initComponent = () => {
|
||||
// eslint-disable-next-line react/display-name
|
||||
return (props: ExternalReferenceAttachmentViewProps) => {
|
||||
const indicatorId: string = props.externalReferenceId;
|
||||
const metadata = props.externalReferenceMetadata as unknown as AttachmentMetadata;
|
|
@ -9,10 +9,10 @@ import React from 'react';
|
|||
import type { StoryFn } from '@storybook/react';
|
||||
import { of } from 'rxjs';
|
||||
import type { IKibanaSearchResponse } from '@kbn/search-types';
|
||||
import { generateMockFileIndicator } from '../../../../common/types/indicator';
|
||||
import { generateMockFileIndicator } from '../../../../../common/threat_intelligence/types/indicator';
|
||||
import { CommentChildren } from './comment_children';
|
||||
import { StoryProvidersComponent } from '../../../mocks/story_providers';
|
||||
import { AttachmentMetadata } from '../utils/attachments';
|
||||
import type { AttachmentMetadata } from '../utils/attachments';
|
||||
|
||||
export default {
|
||||
title: 'CommentChildren',
|
||||
|
@ -44,6 +44,7 @@ export const Default: StoryFn = () => {
|
|||
};
|
||||
|
||||
return (
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
<StoryProvidersComponent kibana={kibana as any}>
|
||||
<CommentChildren id={id} metadata={metadata} />
|
||||
</StoryProvidersComponent>
|
||||
|
@ -72,6 +73,7 @@ export const Loading: StoryFn = () => {
|
|||
};
|
||||
|
||||
return (
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
<StoryProvidersComponent kibana={kibana as any}>
|
||||
<CommentChildren id={id} metadata={metadata} />
|
||||
</StoryProvidersComponent>
|
|
@ -13,10 +13,11 @@ import {
|
|||
INDICATOR_NAME_TEST_ID,
|
||||
INDICATOR_TYPE_TEST_ID,
|
||||
} from './comment_children';
|
||||
import { AttachmentMetadata } from '../utils/attachments';
|
||||
import type { AttachmentMetadata } from '../utils/attachments';
|
||||
import { TestProvidersComponent } from '../../../mocks/test_providers';
|
||||
import { useIndicatorById } from '../hooks/use_indicator_by_id';
|
||||
import { generateMockFileIndicator, Indicator } from '../../../../common/types/indicator';
|
||||
import type { Indicator } from '../../../../../common/threat_intelligence/types/indicator';
|
||||
import { generateMockFileIndicator } from '../../../../../common/threat_intelligence/types/indicator';
|
||||
import { LOADING_LOGO_TEST_ID } from './test_ids';
|
||||
|
||||
jest.mock('../hooks/use_indicator_by_id');
|
|
@ -5,15 +5,16 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { useMemo, useState, VFC } from 'react';
|
||||
import type { FC } from 'react';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiLink, EuiLoadingLogo, EuiText } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { LOADING_LOGO_TEST_ID } from './test_ids';
|
||||
import { Indicator } from '../../../../common/types/indicator';
|
||||
import type { Indicator } from '../../../../../common/threat_intelligence/types/indicator';
|
||||
import { IndicatorsFlyout } from '../../indicators/components/flyout/flyout';
|
||||
import { useStyles } from './styles';
|
||||
import { useIndicatorById } from '../hooks/use_indicator_by_id';
|
||||
import { AttachmentMetadata } from '../utils/attachments';
|
||||
import type { AttachmentMetadata } from '../utils/attachments';
|
||||
|
||||
export const INDICATOR_NAME_TEST_ID = 'tiCasesIndicatorName';
|
||||
export const INDICATOR_FEED_NAME_TEST_ID = 'tiCasesIndicatorFeedName';
|
||||
|
@ -34,7 +35,7 @@ export interface CommentChildrenProps {
|
|||
* Renders some basic values (indicator name, type and feed name) in the comment section
|
||||
* of the case attachment. Also renders a flyout for more details about the indicator.
|
||||
*/
|
||||
export const CommentChildren: VFC<CommentChildrenProps> = ({ id, metadata }) => {
|
||||
export const CommentChildren: FC<CommentChildrenProps> = ({ id, metadata }) => {
|
||||
const styles = useStyles();
|
||||
const [expanded, setExpanded] = useState<boolean>(false);
|
||||
|
||||
|
@ -67,7 +68,7 @@ export const CommentChildren: VFC<CommentChildrenProps> = ({ id, metadata }) =>
|
|||
<EuiText size="s">
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id="xpack.threatIntelligence.cases.indicatorName"
|
||||
id="xpack.securitySolution.threatIntelligence.cases.indicatorName"
|
||||
defaultMessage="Indicator name:"
|
||||
/>
|
||||
</strong>
|
||||
|
@ -87,7 +88,7 @@ export const CommentChildren: VFC<CommentChildrenProps> = ({ id, metadata }) =>
|
|||
<EuiText size="s">
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id="xpack.threatIntelligence.cases.indicatorFeedName"
|
||||
id="xpack.securitySolution.threatIntelligence.cases.indicatorFeedName"
|
||||
defaultMessage="Feed name:"
|
||||
/>
|
||||
</strong>
|
||||
|
@ -105,7 +106,7 @@ export const CommentChildren: VFC<CommentChildrenProps> = ({ id, metadata }) =>
|
|||
<EuiText size="s">
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id="xpack.threatIntelligence.cases.indicatorType"
|
||||
id="xpack.securitySolution.threatIntelligence.cases.indicatorType"
|
||||
defaultMessage="Indicator type:"
|
||||
/>
|
||||
</strong>
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { CSSObject } from '@emotion/react';
|
||||
import type { CSSObject } from '@emotion/react';
|
||||
|
||||
export const useStyles = () => {
|
||||
const container: CSSObject = {
|
|
@ -5,24 +5,27 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { FC, ReactNode } from 'react';
|
||||
import { renderHook, RenderHookResult } from '@testing-library/react';
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
||||
import type { FC, ReactNode } from 'react';
|
||||
import React from 'react';
|
||||
import type { RenderHookResult } from '@testing-library/react';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { casesPluginMock } from '@kbn/cases-plugin/public/mocks';
|
||||
import { KibanaContext } from '../../../hooks/use_kibana';
|
||||
import { useCaseDisabled } from './use_case_permission';
|
||||
import { TestProvidersComponent } from '../../../mocks/test_providers';
|
||||
import { EMPTY_VALUE } from '../../../constants/common';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
|
||||
const casesServiceMock = casesPluginMock.createStartContract();
|
||||
|
||||
const getProviderComponent =
|
||||
(mockedServices: unknown) =>
|
||||
// eslint-disable-next-line react/display-name
|
||||
({ children }: { children: ReactNode }) =>
|
||||
(
|
||||
<TestProvidersComponent>
|
||||
<KibanaContext.Provider value={{ services: mockedServices } as any}>
|
||||
{children}
|
||||
</KibanaContext.Provider>
|
||||
<KibanaContextProvider services={mockedServices as any}>{children}</KibanaContextProvider>
|
||||
</TestProvidersComponent>
|
||||
);
|
||||
|
|
@ -5,9 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { CasesPermissions } from '@kbn/cases-plugin/common';
|
||||
import type { CasesPermissions } from '@kbn/cases-plugin/common';
|
||||
import { EMPTY_VALUE } from '../../../constants/common';
|
||||
import { useKibana } from '../../../hooks/use_kibana';
|
||||
import { useKibana } from '../../../../common/lib/kibana';
|
||||
|
||||
/**
|
||||
* Decides if we enable or disable the add to existing and add to new case features.
|
|
@ -9,7 +9,7 @@ import { waitFor, renderHook } from '@testing-library/react';
|
|||
import { useIndicatorById } from './use_indicator_by_id';
|
||||
import { TestProvidersComponent } from '../../../mocks/test_providers';
|
||||
import { createFetchIndicatorById } from '../services/fetch_indicator_by_id';
|
||||
import { Indicator } from '../../../../common/types/indicator';
|
||||
import type { Indicator } from '../../../../../common/threat_intelligence/types/indicator';
|
||||
|
||||
jest.mock('../services/fetch_indicator_by_id');
|
||||
|
|
@ -7,9 +7,10 @@
|
|||
|
||||
import { useMemo } from 'react';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { Indicator } from '../../../../common/types/indicator';
|
||||
import { useKibana } from '../../../hooks/use_kibana';
|
||||
import { createFetchIndicatorById, FetchParams } from '../services/fetch_indicator_by_id';
|
||||
import type { Indicator } from '../../../../../common/threat_intelligence/types/indicator';
|
||||
import { useKibana } from '../../../../common/lib/kibana';
|
||||
import type { FetchParams } from '../services/fetch_indicator_by_id';
|
||||
import { createFetchIndicatorById } from '../services/fetch_indicator_by_id';
|
||||
|
||||
const QUERY_ID = 'indicatorById';
|
||||
|
|
@ -5,10 +5,10 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { mockedSearchService } from '../../../mocks/test_providers';
|
||||
import { BehaviorSubject, throwError } from 'rxjs';
|
||||
import { createFetchIndicatorById } from './fetch_indicator_by_id';
|
||||
import { RequestAdapter } from '@kbn/inspector-plugin/common';
|
||||
import { mockedSearchService } from '../../../mocks/test_providers';
|
||||
|
||||
const indicatorsResponse = {
|
||||
rawResponse: { hits: { hits: [{ _id: 'testId' }], total: 0 } },
|
||||
|
@ -20,7 +20,9 @@ describe('FetchIndicatorByIdService', () => {
|
|||
describe('fetchIndicatorById()', () => {
|
||||
describe('when query is successful', () => {
|
||||
beforeEach(() => {
|
||||
mockedSearchService.search.mockReturnValue(new BehaviorSubject(indicatorsResponse));
|
||||
jest
|
||||
.mocked(mockedSearchService.search)
|
||||
.mockReturnValue(new BehaviorSubject(indicatorsResponse));
|
||||
});
|
||||
|
||||
it('should pass the query down to searchService', async () => {
|
||||
|
@ -55,9 +57,9 @@ describe('FetchIndicatorByIdService', () => {
|
|||
|
||||
describe('when query fails', () => {
|
||||
beforeEach(() => {
|
||||
mockedSearchService.search.mockReturnValue(
|
||||
throwError(() => new Error('some random exception'))
|
||||
);
|
||||
jest
|
||||
.mocked(mockedSearchService.search)
|
||||
.mockReturnValue(throwError(() => new Error('some random exception')));
|
||||
});
|
||||
|
||||
it('should throw an error', async () => {
|
|
@ -5,10 +5,10 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ISearchStart } from '@kbn/data-plugin/public';
|
||||
import { RequestAdapter } from '@kbn/inspector-plugin/common';
|
||||
import type { ISearchStart } from '@kbn/data-plugin/public';
|
||||
import type { RequestAdapter } from '@kbn/inspector-plugin/common';
|
||||
import { search } from '../../../utils/search';
|
||||
import { Indicator } from '../../../../common/types/indicator';
|
||||
import type { Indicator } from '../../../../../common/threat_intelligence/types/indicator';
|
||||
|
||||
interface FetchIndicatorsDependencies {
|
||||
searchService: ISearchStart;
|
||||
|
@ -21,6 +21,7 @@ interface FetchIndicatorsDependencies {
|
|||
|
||||
export interface RawIndicatorsResponse {
|
||||
hits: {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
hits: any[];
|
||||
total: number;
|
||||
};
|
|
@ -5,13 +5,11 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { CaseAttachmentsWithoutOwner } from '@kbn/cases-plugin/public';
|
||||
import { generateMockFileIndicator, Indicator } from '../../../../common/types/indicator';
|
||||
import {
|
||||
AttachmentMetadata,
|
||||
generateAttachmentsMetadata,
|
||||
generateAttachmentsWithoutOwner,
|
||||
} from './attachments';
|
||||
import type { CaseAttachmentsWithoutOwner } from '@kbn/cases-plugin/public';
|
||||
import type { Indicator } from '../../../../../common/threat_intelligence/types/indicator';
|
||||
import { generateMockFileIndicator } from '../../../../../common/threat_intelligence/types/indicator';
|
||||
import type { AttachmentMetadata } from './attachments';
|
||||
import { generateAttachmentsMetadata, generateAttachmentsWithoutOwner } from './attachments';
|
||||
|
||||
describe('generateAttachmentsWithoutOwner', () => {
|
||||
it('should return empty array if external reference id is empty', () => {
|
|
@ -5,16 +5,17 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { CaseAttachmentsWithoutOwner } from '@kbn/cases-plugin/public';
|
||||
import type { CaseAttachmentsWithoutOwner } from '@kbn/cases-plugin/public';
|
||||
import { AttachmentType, ExternalReferenceStorageType } from '@kbn/cases-plugin/common';
|
||||
import { JsonValue } from '@kbn/utility-types';
|
||||
import { ExternalReferenceAttachmentType } from '@kbn/cases-plugin/public/client/attachment_framework/types';
|
||||
import type { JsonValue } from '@kbn/utility-types';
|
||||
import type { ExternalReferenceAttachmentType } from '@kbn/cases-plugin/public/client/attachment_framework/types';
|
||||
import React from 'react';
|
||||
import { EuiAvatar } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { CASE_ATTACHMENT_TYPE_ID } from '../../../../common/constants';
|
||||
import { CASE_ATTACHMENT_TYPE_ID } from '../../../../../common/threat_intelligence/constants';
|
||||
import { EMPTY_VALUE } from '../../../constants/common';
|
||||
import { Indicator, RawIndicatorFieldId } from '../../../../common/types/indicator';
|
||||
import type { Indicator } from '../../../../../common/threat_intelligence/types/indicator';
|
||||
import { RawIndicatorFieldId } from '../../../../../common/threat_intelligence/types/indicator';
|
||||
import { getIndicatorFieldAndValue } from '../../indicators/utils/field_value';
|
||||
|
||||
/**
|
||||
|
@ -45,7 +46,7 @@ export const generateAttachmentType = (): ExternalReferenceAttachmentType => ({
|
|||
getAttachmentViewObject: () => ({
|
||||
event: (
|
||||
<FormattedMessage
|
||||
id="xpack.threatIntelligence.cases.eventDescription"
|
||||
id="xpack.securitySolution.threatIntelligence.cases.eventDescription"
|
||||
defaultMessage="added an indicator of compromise"
|
||||
/>
|
||||
),
|
|
@ -31,6 +31,7 @@ export function BasicEmptyPage() {
|
|||
};
|
||||
|
||||
return (
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
<StoryProvidersComponent kibana={kibana as any}>
|
||||
<EmptyPage />
|
||||
</StoryProvidersComponent>
|
|
@ -14,6 +14,7 @@ import { useIntegrationsPageLink } from '../../hooks/use_integrations_page_link'
|
|||
|
||||
jest.mock('../../hooks/use_integrations_page_link');
|
||||
jest.mock('../../hooks/use_documentation_link');
|
||||
jest.mock('../../containers/security_solution_plugin_template_wrapper');
|
||||
|
||||
const INTEGRATION_HREF = 'INTEGRATION_HREF';
|
||||
const DOCUMENTATION_HREF = 'DOCUMENTATION_HREF';
|
|
@ -5,7 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { VFC } from 'react';
|
||||
import type { FC } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
import { EuiButton, EuiEmptyPrompt, EuiImage, EuiLink } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
|
@ -19,7 +20,7 @@ export const DOCS_LINK_TEST_ID = 'tiEmptyPageDocsLink';
|
|||
export const EMPTY_PROMPT_TEST_ID = 'tiEmptyPage';
|
||||
export const INTEGRATION_LINK_ID = 'tiEmptyPageIntegrationsPageLink';
|
||||
|
||||
export const EmptyPage: VFC = () => {
|
||||
export const EmptyPage: FC = () => {
|
||||
const integrationsPageLink = useIntegrationsPageLink();
|
||||
const documentationLink = useTIDocumentationLink();
|
||||
|
||||
|
@ -32,7 +33,7 @@ export const EmptyPage: VFC = () => {
|
|||
title={
|
||||
<h3>
|
||||
<FormattedMessage
|
||||
id="xpack.threatIntelligence.common.emptyPage.title"
|
||||
id="xpack.securitySolution.threatIntelligence.common.emptyPage.title"
|
||||
defaultMessage="Get started with Elastic Threat Intelligence"
|
||||
/>
|
||||
</h3>
|
||||
|
@ -44,21 +45,21 @@ export const EmptyPage: VFC = () => {
|
|||
<>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.threatIntelligence.common.emptyPage.body1"
|
||||
id="xpack.securitySolution.threatIntelligence.common.emptyPage.body1"
|
||||
defaultMessage="Elastic Threat Intelligence makes it easy to analyze and investigate potential security
|
||||
threats by aggregating data from multiple sources in one place."
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.threatIntelligence.common.emptyPage.body2"
|
||||
id="xpack.securitySolution.threatIntelligence.common.emptyPage.body2"
|
||||
defaultMessage="You’ll be able to view data from all activated threat intelligence feeds and take action
|
||||
from this page."
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.threatIntelligence.common.emptyPage.body3"
|
||||
id="xpack.securitySolution.threatIntelligence.common.emptyPage.body3"
|
||||
defaultMessage="To get started with Elastic Threat Intelligence, enable one or more Threat Intelligence
|
||||
Integrations from the Integrations page or ingest data using filebeat. For more
|
||||
information, view the {docsLink}."
|
||||
|
@ -70,7 +71,7 @@ export const EmptyPage: VFC = () => {
|
|||
data-test-subj={DOCS_LINK_TEST_ID}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.threatIntelligence.common.emptyPage.docsLinkText"
|
||||
id="xpack.securitySolution.threatIntelligence.common.emptyPage.docsLinkText"
|
||||
defaultMessage="Security app documentation"
|
||||
/>
|
||||
</EuiLink>
|
||||
|
@ -89,7 +90,7 @@ export const EmptyPage: VFC = () => {
|
|||
fill
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.threatIntelligence.common.emptyPage.buttonText"
|
||||
id="xpack.securitySolution.threatIntelligence.common.emptyPage.buttonText"
|
||||
defaultMessage="Add Integrations"
|
||||
/>
|
||||
</EuiButton>
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 89 KiB |
|
@ -7,6 +7,9 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export const IMAGE = i18n.translate('xpack.threatIntelligence.common.emptyPage.imgAlt', {
|
||||
defaultMessage: 'Enable Threat Intelligence Integrations',
|
||||
});
|
||||
export const IMAGE = i18n.translate(
|
||||
'xpack.securitySolution.threatIntelligence.common.emptyPage.imgAlt',
|
||||
{
|
||||
defaultMessage: 'Enable Threat Intelligence Integrations',
|
||||
}
|
||||
);
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue