main
vue 136 lines 3.86 KB
Raw
1 <template>
2 <div>
3 <LicenseFeatureCheck
4 feature="SOCFORTRESS AI"
5 feedback="tooltip"
6 :disabled="disabledLicenseCheck"
7 :force-show-feedback="disabledLicenseCheck && !licenseResponse"
8 @response="
9 (() => {
10 licenseChecked = true
11 licenseResponse = $event
12 })()
13 "
14 @start-loading="licenseChecking = true"
15 @stop-loading="licenseChecking = false"
16 >
17 <n-button
18 :size="size || 'small'"
19 ghost
20 type="primary"
21 :loading="loading || licenseChecking"
22 :disabled="!licenseChecked || !licenseResponse"
23 @click="analysis()"
24 >
25 <template #icon>
26 <Icon :name="AiIcon" />
27 </template>
28 <div class="flex items-center gap-2">
29 <span>Generate Wazuh Exclusion Rule</span>
30 <Icon v-if="!licenseResponse && licenseChecked" :name="LockIcon" :size="14" />
31 </div>
32 </n-button>
33 </LicenseFeatureCheck>
34
35 <n-modal
36 v-model:show="showModal"
37 preset="card"
38 content-class="p-0!"
39 :style="{ maxWidth: 'min(710px, 90vw)', minHeight: 'min(500px, 90vh)' }"
40 :bordered="false"
41 title="Wazuh Exclusion Rule"
42 segmented
43 >
44 <div
45 v-if="analysisResponse?.wazuh_exclusion_rule || analysisResponse?.wazuh_exclusion_rule_justification"
46 class="flex flex-col gap-7 p-7"
47 >
48 <div v-if="analysisResponse?.wazuh_exclusion_rule">
49 <CodeSource :code="analysisResponse.wazuh_exclusion_rule" decode />
50 </div>
51 <div v-if="analysisResponse?.wazuh_exclusion_rule_justification">
52 <Markdown :source="analysisResponse.wazuh_exclusion_rule_justification" />
53 </div>
54 </div>
55 <n-empty v-else description="No rules found" class="h-48 justify-center" />
56 </n-modal>
57 </div>
58 </template>
59
60 <script setup lang="ts">
61 import type { ButtonSize } from "naive-ui"
62 import type { AiWazuhExclusionRuleResponse } from "@/types/threatIntel.d"
63 import { NButton, NEmpty, NModal, useMessage } from "naive-ui"
64 import { defineAsyncComponent, ref, watchEffect } from "vue"
65 import Api from "@/api"
66 import Icon from "@/components/common/Icon.vue"
67 import LicenseFeatureCheck from "@/components/license/LicenseFeatureCheck.vue"
68
69 const {
70 indexName,
71 indexId,
72 alertId,
73 forceLicenseResponse = undefined,
74 size
75 } = defineProps<{
76 indexName: string
77 indexId: string
78 alertId: number
79 forceLicenseResponse?: boolean
80 size?: ButtonSize
81 }>()
82
83 const CodeSource = defineAsyncComponent(() => import("@/components/common/CodeSource.vue"))
84 const Markdown = defineAsyncComponent(() => import("@/components/common/Markdown.vue"))
85
86 const LockIcon = "carbon:locked"
87 const AiIcon = "mage:stars-c"
88 const showModal = ref<boolean>(false)
89 const loading = ref<boolean>(false)
90 const message = useMessage()
91 const analysisResponse = ref<AiWazuhExclusionRuleResponse | null>(null)
92 const licenseChecking = ref(false)
93 const licenseChecked = ref(forceLicenseResponse !== undefined)
94 const licenseResponse = ref(forceLicenseResponse ?? false)
95 const disabledLicenseCheck = ref(forceLicenseResponse !== undefined)
96 const WAZUH_RULE_BACKSLASH_REGEX = /\\\\/g
97
98 function openResponse() {
99 showModal.value = true
100 }
101
102 function analysis() {
103 loading.value = true
104
105 Api.threatIntel
106 .aiWazuhExclusionRule({ indexName, indexId, alertId })
107 .then(res => {
108 if (res.data.success) {
109 analysisResponse.value = res.data
110
111 if (res.data.wazuh_exclusion_rule) {
112 analysisResponse.value.wazuh_exclusion_rule = res.data.wazuh_exclusion_rule.replace(
113 WAZUH_RULE_BACKSLASH_REGEX,
114 "\\\\\\\\"
115 )
116 }
117
118 openResponse()
119 } else {
120 message.warning(res.data?.message || "An error occurred. Please try again later.")
121 }
122 })
123 .catch(err => {
124 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
125 })
126 .finally(() => {
127 loading.value = false
128 })
129 }
130
131 watchEffect(() => {
132 licenseResponse.value = forceLicenseResponse ?? false
133 licenseChecked.value = forceLicenseResponse !== undefined
134 disabledLicenseCheck.value = forceLicenseResponse !== undefined
135 })
136 </script>