main
vue 250 lines 6.22 KB
Raw
1 <template>
2 <div class="flex flex-wrap justify-end gap-2">
3 <n-button v-if="socAlertFieldValue" type="success" secondary :size @click.stop="gotoSocAlertUrl()">
4 <template #icon>
5 <Icon :name="ViewIcon" />
6 </template>
7 View SOC Alert
8 </n-button>
9 <n-button
10 v-if="!socAlertFieldValue"
11 :loading="loadingSocAlert"
12 type="warning"
13 secondary
14 :size
15 @click.stop="createAlert()"
16 >
17 <template #icon>
18 <Icon :name="DangerIcon" />
19 </template>
20 Create SOC Alert
21 </n-button>
22 <n-button v-if="alertAskMessage" type="success" secondary :size @click.stop="showSocResponse = true">
23 <template #icon>
24 <Icon :name="ViewIcon" />
25 </template>
26 View SOCFortress Response
27 </n-button>
28 <n-button
29 v-if="isAskVisible"
30 :loading="loadingAskSoc"
31 type="warning"
32 secondary
33 :size
34 @click.stop="askSOCFortress()"
35 >
36 <template #icon>
37 <Icon :name="AskIcon" />
38 </template>
39 Ask SOCFortress
40 </n-button>
41 <!-- <n-button
42 v-if="isWazuhRulesVisible"
43 :loading="loadingWazuhRuleExclude"
44 secondary
45 :size
46 @click.stop="wazuhManagerRuleExclude()"
47 >
48 <template #icon>
49 <Icon :name="RulesIcon"/>
50 </template>
51 Exclude Rule in Wazuh
52 </n-button> -->
53
54 <n-modal
55 v-model:show="showSocResponse"
56 preset="card"
57 :style="{ maxWidth: 'min(800px, 90vw)', overflow: 'hidden' }"
58 title="SOCFortress Response"
59 :bordered="false"
60 segmented
61 >
62 <n-input
63 :value="alertAskMessage"
64 type="textarea"
65 readonly
66 placeholder="SOCFortress Response"
67 size="large"
68 :autosize="{
69 minRows: 3
70 }"
71 />
72 </n-modal>
73
74 <n-modal
75 v-model:show="showWazuhRuleExclude"
76 preset="card"
77 :style="{ maxWidth: 'min(800px, 90vw)', overflow: 'hidden' }"
78 title="Recommended exclusion for a Wazuh Rule"
79 :bordered="false"
80 content-class="p-0!"
81 segmented
82 >
83 <AlertWazuhRules v-if="wazuhRuleData" :data="wazuhRuleData" />
84 </n-modal>
85 </div>
86 </template>
87
88 <script setup lang="ts">
89 import type { ButtonSize } from "naive-ui"
90 import type { SocAlertField } from "./type.d"
91 import type { Alert, WazuhRuleExclude } from "@/types/alerts.d"
92 import { NButton, NInput, NModal, useMessage } from "naive-ui"
93 import { computed, onBeforeMount, ref, watch } from "vue"
94 import { useRouter } from "vue-router"
95 import Api from "@/api"
96 import Icon from "@/components/common/Icon.vue"
97 import AlertWazuhRules from "./AlertWazuhRules.vue"
98
99 const { alert, size, socAlertField } = defineProps<{
100 alert: Alert
101 size?: ButtonSize
102 socAlertField: SocAlertField
103 }>()
104
105 const emit = defineEmits<{
106 (e: "startLoading"): void
107 (e: "stopLoading"): void
108 (e: "updatedUrl", value: string): void
109 (e: "updatedId", value: number): void
110 (e: "updatedAskMessage", value: string): void
111 }>()
112
113 const DangerIcon = "majesticons:exclamation-line"
114 const AskIcon = "majesticons:question-mark-circle-line"
115 const ViewIcon = "iconoir:eye-solid"
116 // const RulesIcon = "carbon:rule-cancelled"
117
118 const router = useRouter()
119 const message = useMessage()
120 const showSocResponse = ref(false)
121 const showWazuhRuleExclude = ref(false)
122 const loadingSocAlert = ref(false)
123 const loadingAskSoc = ref(false)
124 const loadingWazuhRuleExclude = ref(false)
125 const loading = computed(() => loadingSocAlert.value || loadingAskSoc.value || loadingWazuhRuleExclude.value)
126
127 const alertUrl = ref("")
128 const alertId = ref(0)
129 const alertAskMessage = ref("")
130 const wazuhRuleData = ref<WazuhRuleExclude | null>(null)
131
132 const socAlertFieldValue = computed(() => (socAlertField === "alert_id" ? alertId.value : alertUrl.value))
133
134 const isAskVisible = computed(() => alert._source?.rule_group3 === "sigma" && !alertAskMessage.value)
135 // const _isWazuhRulesVisible = computed(() => alert._source)
136
137 watch(loading, val => {
138 if (val) {
139 emit("startLoading")
140 } else {
141 emit("stopLoading")
142 }
143 })
144
145 watch(alertUrl, val => {
146 if (val) {
147 emit("updatedUrl", val)
148 }
149 })
150
151 watch(alertId, val => {
152 if (val) {
153 emit("updatedId", val)
154 }
155 })
156
157 watch(alertAskMessage, val => {
158 if (val) {
159 emit("updatedAskMessage", val)
160 }
161 })
162
163 function gotoSocAlertUrl() {
164 if (socAlertField === "alert_url") {
165 window.open(alertUrl.value, "_blank")
166 } else if (socAlertField === "alert_id") {
167 router.push({ name: "IncidentManagement-Alerts", query: alertId.value ? { alert_id: alertId.value } : {} })
168 }
169 }
170
171 function askSOCFortress() {
172 loadingAskSoc.value = true
173
174 Api.askSocfortress
175 .create(alert._index, alert._id)
176 .then(res => {
177 if (res.data.success) {
178 res.data.message && (alertAskMessage.value = res.data.message)
179 message.success("Asked SOCFortress Sigma.")
180 } else {
181 message.warning(res.data?.message || "An error occurred. Please try again later.")
182 }
183 })
184 .catch(err => {
185 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
186 })
187 .finally(() => {
188 loadingAskSoc.value = false
189 })
190 }
191
192 /*
193 function wazuhManagerRuleExclude() {
194 if (wazuhRuleData.value) {
195 showWazuhRuleExclude.value = true
196 return
197 }
198
199 loadingWazuhRuleExclude.value = true
200
201 Api.wazuh.rules
202 .wazuhManagerRuleExclude(alert._source)
203 .then(res => {
204 if (res.data.success) {
205 wazuhRuleData.value = {
206 wazuh_rule: res.data.wazuh_rule,
207 explanation: res.data.explanation
208 }
209 showWazuhRuleExclude.value = true
210 } else {
211 message.warning(res.data?.message || "An error occurred. Please try again later.")
212 }
213 })
214 .catch(err => {
215 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
216 })
217 .finally(() => {
218 loadingWazuhRuleExclude.value = false
219 })
220 }
221 */
222
223 function createAlert() {
224 loadingSocAlert.value = true
225
226 Api.alerts
227 .create(alert._index, alert._id)
228 .then(res => {
229 if (res.data.success) {
230 res.data.alert_url && (alertUrl.value = res.data.alert_url)
231 res.data.alert_id && (alertId.value = res.data.alert_id)
232 message.success(res.data?.message || "SOC Alert created.")
233 } else {
234 message.warning(res.data?.message || "An error occurred. Please try again later.")
235 }
236 })
237 .catch(err => {
238 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
239 })
240 .finally(() => {
241 loadingSocAlert.value = false
242 })
243 }
244
245 onBeforeMount(() => {
246 alertUrl.value = alert._source.alert_url || ""
247 alertId.value = alert._source.alert_id || 0
248 alertAskMessage.value = alert._source.ask_socfortress_message || ""
249 })
250 </script>