1
<template>
2
- <n-spin :show="loading" class="creation-report-form">
3
- <n-form ref="formRef" :model="form" :rules="rules">
4
- <div class="flex flex-col gap-8">
5
- <div class="flex flex-col gap-2">
6
- <n-form-item v-if="showIndexNameField" label="Index name" path="index_name">
7
- <n-select
8
- v-model:value="form.index_name"
9
- :options="indexNamesOptions"
10
- placeholder="Select..."
11
- clearable
12
- filterable
13
- to="body"
14
- :disabled="disableIndexNameField"
15
- :loading="loadingIndexNames"
16
- />
17
- </n-form-item>
18
-
19
- <div v-if="showSourceField">
20
- <n-form-item path="source" :show-require-mark="false" class="source-field">
21
- <template #label>
22
- <div class="flex items-end justify-between gap-2">
23
- <span>
24
- Source
25
- <span class="n-form-item-label__asterisk">*</span>
26
- </span>
27
-
28
- <span v-if="isSocfortressRecommendsAvailable">
29
- <n-button
30
- :loading="loadingSocfortressRecommendsWazuh"
31
- size="tiny"
32
- ghost
33
- type="primary"
34
- @click="getSocfortressRecommendsWazuh()"
35
- >
36
- SOCFortress Recommends
37
- </n-button>
38
- </span>
39
- </div>
40
- </template>
41
- <n-input
42
- v-if="arbitrarySourceField"
43
- v-model:value.trim="form.source"
44
- placeholder="Please insert Source"
45
- clearable
46
- />
47
- <n-input
48
- v-else
49
- v-model:value.trim="form.source"
50
- placeholder="Please insert Source"
51
- clearable
52
- :disabled="disableSourceField"
53
- :loading="loadingSource"
54
- @update:value="resetIndexAvailable()"
55
- />
56
- </n-form-item>
57
- </div>
58
-
59
- <n-alert v-if="isSourceNotAllowed" title="Source already exists" type="warning" class="mb-5">
60
- A configuration for
61
- <strong>"{{ form.source }}"</strong>
62
- already exists. Please select a different
63
- <strong>Index name</strong>
64
- to proceed.
65
- </n-alert>
66
-
67
- <n-alert
68
- v-if="arbitrarySourceField"
69
- title="Proceed with caution, incorrect settings can disrupt system operation"
70
- type="warning"
71
- class="mb-5"
72
- ></n-alert>
73
-
74
- <n-form-item label="Field names" path="field_names">
75
- <n-select
76
- v-model:value="form.field_names"
77
- :options="availableMappingsOptions"
78
- placeholder="Select..."
79
- clearable
80
- filterable
81
- multiple
82
- :tag="arbitrarySourceField"
83
- to="body"
84
- :disabled="!isFieldEnabled"
85
- :loading="loadingAvailableMappings"
86
- >
87
- <template v-if="arbitrarySourceField" #empty>Press Enter to add the typed value</template>
88
- </n-select>
89
- </n-form-item>
90
- <n-form-item label="IOC Field names" path="ioc_field_names">
91
- <n-select
92
- v-model:value="form.ioc_field_names"
93
- :options="availableMappingsOptions"
94
- placeholder="Select..."
95
- clearable
96
- filterable
97
- multiple
98
- :tag="arbitrarySourceField"
99
- to="body"
100
- :disabled="!isFieldEnabled"
101
- :loading="loadingAvailableMappings"
102
- >
103
- <template v-if="arbitrarySourceField" #empty>Press Enter to add the typed value</template>
104
- </n-select>
105
- </n-form-item>
106
- <n-form-item path="asset_name_array" :show-require-mark="false">
107
- <template #label>
108
- <div class="flex flex-col gap-1">
109
- <span>
110
- Asset name fields
111
- <span class="n-form-item-label__asterisk">*</span>
112
- </span>
113
- <n-text depth="3" style="font-size: 11px; font-weight: 400">
114
- Add multiple fields. First field has priority (checked first).
115
- </n-text>
116
- </div>
117
- </template>
118
- <n-dynamic-tags
119
- v-model:value="form.asset_name_array"
120
- :max="10"
121
- :disabled="!isFieldEnabled"
122
- :render-tag="renderAssetTag"
123
- >
124
- <template #input="{ submit, deactivate }">
125
- <n-auto-complete
126
- v-model:value="assetNameInput"
127
- :options="filteredAssetNameOptions"
128
- :disabled="!isFieldEnabled"
129
- placeholder="Type or select field name"
130
- @select="handleAssetSelect($event, submit)"
131
- @blur="deactivate"
132
- @keyup.enter="handleAssetEnter(submit)"
133
- />
134
- </template>
135
- <template #trigger="{ activate, disabled }">
136
- <n-button
137
- size="small"
138
- type="primary"
139
- dashed
140
- :disabled="disabled || !isFieldEnabled"
141
- @click="activate()"
142
- >
143
- <template #icon>
144
- <Icon :name="AddIcon" />
145
- </template>
146
- Add Field
147
- </n-button>
148
- </template>
149
- </n-dynamic-tags>
150
- </n-form-item>
151
- <n-form-item label="Timefield name" path="timefield_name">
152
- <n-select
153
- v-model:value="form.timefield_name"
154
- :options="availableMappingsOptions"
155
- placeholder="Select..."
156
- clearable
157
- filterable
158
- :tag="arbitrarySourceField"
159
- to="body"
160
- :disabled="!isFieldEnabled"
161
- :loading="loadingAvailableMappings"
162
- >
163
- <template v-if="arbitrarySourceField" #empty>Press Enter to add the typed value</template>
164
- </n-select>
165
- </n-form-item>
166
- <n-form-item label="Alert title name" path="alert_title_name">
167
- <n-select
168
- v-model:value="form.alert_title_name"
169
- :options="availableMappingsOptions"
170
- placeholder="Select..."
171
- clearable
172
- filterable
173
- :tag="arbitrarySourceField"
174
- to="body"
175
- :disabled="!isFieldEnabled"
176
- :loading="loadingAvailableMappings"
177
- >
178
- <template v-if="arbitrarySourceField" #empty>Press Enter to add the typed value</template>
179
- </n-select>
180
- </n-form-item>
181
- </div>
182
- <div class="flex justify-between gap-3">
183
- <div>
184
- <slot name="additionalActions"></slot>
185
- </div>
186
- <div class="flex items-center gap-3">
187
- <n-button :disabled="loading" @click="reset()">Reset</n-button>
188
- <n-button
189
- type="primary"
190
- :disabled="!isValid"
191
- :loading="submitting"
192
- @click="validate(() => submit())"
193
- >
194
- Submit
195
- </n-button>
196
- </div>
197
- </div>
198
- </div>
199
- </n-form>
200
- </n-spin>
2
+ <n-spin :show="loading" class="creation-report-form">
3
+ <n-form ref="formRef" :model="form" :rules="rules">
4
+ <div class="flex flex-col gap-8">
5
+ <div class="flex flex-col gap-2">
6
+ <n-form-item v-if="showIndexNameField" label="Index name" path="index_name">
7
+ <n-select
8
+ v-model:value="form.index_name"
9
+ :options="indexNamesOptions"
10
+ placeholder="Select..."
11
+ clearable
12
+ filterable
13
+ to="body"
14
+ :disabled="disableIndexNameField"
15
+ :loading="loadingIndexNames"
16
+ />
17
+ </n-form-item>
18
+
19
+ <div v-if="showSourceField">
20
+ <n-form-item path="source" :show-require-mark="false" class="source-field">
21
+ <template #label>
22
+ <div class="flex items-end justify-between gap-2">
23
+ <span>
24
+ Source
25
+ <span class="n-form-item-label__asterisk">*</span>
26
+ </span>
27
+
28
+ <span v-if="isSocfortressRecommendsAvailable">
29
+ <n-button
30
+ :loading="loadingSocfortressRecommendsWazuh"
31
+ size="tiny"
32
+ ghost
33
+ type="primary"
34
+ @click="getSocfortressRecommendsWazuh()"
35
+ >
36
+ SOCFortress Recommends
37
+ </n-button>
38
+ </span>
39
+ </div>
40
+ </template>
41
+ <n-input
42
+ v-if="arbitrarySourceField"
43
+ v-model:value.trim="form.source"
44
+ placeholder="Please insert Source"
45
+ clearable
46
+ />
47
+ <n-input
48
+ v-else
49
+ v-model:value.trim="form.source"
50
+ placeholder="Please insert Source"
51
+ clearable
52
+ :disabled="disableSourceField"
53
+ :loading="loadingSource"
54
+ @update:value="resetIndexAvailable()"
55
+ />
56
+ </n-form-item>
57
+ </div>
58
+
59
+ <n-alert v-if="isSourceNotAllowed" title="Source already exists" type="warning" class="mb-5">
60
+ A configuration for
61
+ <strong>"{{ form.source }}"</strong>
62
+ already exists. Please select a different
63
+ <strong>Index name</strong>
64
+ to proceed.
65
+ </n-alert>
66
+
67
+ <n-alert
68
+ v-if="arbitrarySourceField"
69
+ title="Proceed with caution, incorrect settings can disrupt system operation"
70
+ type="warning"
71
+ class="mb-5"
72
+ ></n-alert>
73
+
74
+ <n-form-item label="Field names" path="field_names">
75
+ <n-select
76
+ v-model:value="form.field_names"
77
+ :options="availableMappingsOptions"
78
+ placeholder="Select..."
79
+ clearable
80
+ filterable
81
+ multiple
82
+ :tag="arbitrarySourceField"
83
+ to="body"
84
+ :disabled="!isFieldEnabled"
85
+ :loading="loadingAvailableMappings"
86
+ >
87
+ <template v-if="arbitrarySourceField" #empty>Press Enter to add the typed value</template>
88
+ </n-select>
89
+ </n-form-item>
90
+ <n-form-item label="IOC Field names" path="ioc_field_names">
91
+ <n-select
92
+ v-model:value="form.ioc_field_names"
93
+ :options="availableMappingsOptions"
94
+ placeholder="Select..."
95
+ clearable
96
+ filterable
97
+ multiple
98
+ :tag="arbitrarySourceField"
99
+ to="body"
100
+ :disabled="!isFieldEnabled"
101
+ :loading="loadingAvailableMappings"
102
+ >
103
+ <template v-if="arbitrarySourceField" #empty>Press Enter to add the typed value</template>
104
+ </n-select>
105
+ </n-form-item>
106
+ <n-form-item path="asset_name_array" :show-require-mark="false">
107
+ <template #label>
108
+ <div class="flex flex-col gap-1">
109
+ <span>
110
+ Asset name fields
111
+ <span class="n-form-item-label__asterisk">*</span>
112
+ </span>
113
+ <small class="text-secondary">
114
+ Add multiple fields. First field has priority (checked first).
115
+ </small>
116
+ </div>
117
+ </template>
118
+ <n-dynamic-tags
119
+ v-model:value="form.asset_name_array"
120
+ :max="10"
121
+ :disabled="!isFieldEnabled"
122
+ :render-tag="renderAssetTag"
123
+ >
124
+ <template #input="{ submit, deactivate }">
125
+ <n-auto-complete
126
+ v-model:value="assetNameInput"
127
+ :options="filteredAssetNameOptions"
128
+ :disabled="!isFieldEnabled"
129
+ placeholder="Type or select field name"
130
+ @select="handleAssetSelect($event, submit)"
131
+ @blur="deactivate"
132
+ @keyup.enter="handleAssetEnter(submit)"
133
+ />
134
+ </template>
135
+ <template #trigger="{ activate, disabled }">
136
+ <n-button
137
+ size="small"
138
+ type="primary"
139
+ dashed
140
+ :disabled="disabled || !isFieldEnabled"
141
+ @click="activate()"
142
+ >
143
+ <template #icon>
144
+ <Icon :name="AddIcon" />
145
+ </template>
146
+ Add Field
147
+ </n-button>
148
+ </template>
149
+ </n-dynamic-tags>
150
+ </n-form-item>
151
+ <n-form-item label="Timefield name" path="timefield_name">
152
+ <n-select
153
+ v-model:value="form.timefield_name"
154
+ :options="availableMappingsOptions"
155
+ placeholder="Select..."
156
+ clearable
157
+ filterable
158
+ :tag="arbitrarySourceField"
159
+ to="body"
160
+ :disabled="!isFieldEnabled"
161
+ :loading="loadingAvailableMappings"
162
+ >
163
+ <template v-if="arbitrarySourceField" #empty>Press Enter to add the typed value</template>
164
+ </n-select>
165
+ </n-form-item>
166
+ <n-form-item label="Alert title name" path="alert_title_name">
167
+ <n-select
168
+ v-model:value="form.alert_title_name"
169
+ :options="availableMappingsOptions"
170
+ placeholder="Select..."
171
+ clearable
172
+ filterable
173
+ :tag="arbitrarySourceField"
174
+ to="body"
175
+ :disabled="!isFieldEnabled"
176
+ :loading="loadingAvailableMappings"
177
+ >
178
+ <template v-if="arbitrarySourceField" #empty>Press Enter to add the typed value</template>
179
+ </n-select>
180
+ </n-form-item>
181
+ </div>
182
+ <div class="flex justify-between gap-3">
183
+ <div>
184
+ <slot name="additionalActions"></slot>
185
+ </div>
186
+ <div class="flex items-center gap-3">
187
+ <n-button :disabled="loading" @click="reset()">Reset</n-button>
188
+ <n-button
189
+ type="primary"
190
+ :disabled="!isValid"
191
+ :loading="submitting"
192
+ @click="validate(() => submitForm())"
193
+ >
194
+ Submit
195
+ </n-button>
196
+ </div>
197
+ </div>
198
+ </div>
199
+ </n-form>
200
+ </n-spin>
201
</template>
202
203
<script setup lang="ts">
204
import type { FormInst, FormItemRule, FormRules, FormValidationError, MessageReactive } from "naive-ui"
205
import type { SourceConfiguration, SourceConfigurationModel, SourceName } from "@/types/incidentManagement/sources.d"
206
import _intersection from "lodash/intersection"
207
-import { NAlert, NButton, NForm, NFormItem, NInput, NSelect, NSpin, NDynamicTags, NAutoComplete, NTag, NText, useMessage } from "naive-ui"
207
+import {
208
+ NAlert,
209
+ NAutoComplete,
210
+ NButton,
211
+ NDynamicTags,
212
+ NForm,
213
+ NFormItem,
214
+ NInput,
215
+ NSelect,
216
+ NSpin,
217
+ NTag,
218
+ NText,
219
+ useMessage
220
+} from "naive-ui"
221
import { computed, h, onBeforeMount, onMounted, ref, toRefs, watch } from "vue"
222
import Api from "@/api"
223
import Icon from "@/components/common/Icon.vue"
224
212
-const AddIcon = "carbon:add"
213
-
225
const props = defineProps<{
215
- sourceConfigurationModel?: SourceConfigurationModel
216
- showSourceField?: boolean
217
- arbitrarySourceField?: boolean
218
- disableSourceField?: boolean
219
- showIndexNameField?: boolean
220
- disableIndexNameField?: boolean
221
- applyFieldsSanitize?: boolean
222
- disabledSources?: SourceName[]
226
+ sourceConfigurationModel?: SourceConfigurationModel
227
+ showSourceField?: boolean
228
+ arbitrarySourceField?: boolean
229
+ disableSourceField?: boolean
230
+ showIndexNameField?: boolean
231
+ disableIndexNameField?: boolean
232
+ applyFieldsSanitize?: boolean
233
+ disabledSources?: SourceName[]
234
}>()
235
236
const emit = defineEmits<{
226
- (e: "submitted", value: SourceConfiguration): void
227
- (
228
- e: "mounted",
229
- value: {
230
- reset: () => void
231
- toggleSubmittingFlag: () => boolean
232
- }
233
- ): void
237
+ (e: "submitted", value: SourceConfiguration): void
238
+ (
239
+ e: "mounted",
240
+ value: {
241
+ reset: () => void
242
+ toggleSubmittingFlag: () => boolean
243
+ }
244
+ ): void
245
}>()
246
247
+const AddIcon = "carbon:add"
248
+
249
const {
237
- sourceConfigurationModel,
238
- showSourceField,
239
- arbitrarySourceField,
240
- disableSourceField,
241
- showIndexNameField,
242
- disableIndexNameField,
243
- applyFieldsSanitize,
244
- disabledSources
250
+ sourceConfigurationModel,
251
+ showSourceField,
252
+ arbitrarySourceField,
253
+ disableSourceField,
254
+ showIndexNameField,
255
+ disableIndexNameField,
256
+ applyFieldsSanitize,
257
+ disabledSources
258
} = toRefs(props)
259
260
const submitting = ref(false)
272
const assetNameInput = ref("")
273
274
const rules: FormRules = {
262
- source: {
263
- required: true,
264
- message: "Please input the Source",
265
- trigger: ["input", "blur"]
266
- },
267
- field_names: {
268
- required: true,
269
- validator: validateAtLeastOne,
270
- trigger: ["input", "blur"]
271
- },
272
- asset_name_array: {
273
- required: true,
274
- validator: validateAtLeastOneAsset,
275
- trigger: ["input", "blur", "change"]
276
- },
277
- timefield_name: {
278
- required: true,
279
- message: "Please input the timefield name",
280
- trigger: ["input", "blur"]
281
- },
282
- alert_title_name: {
283
- required: true,
284
- message: "Please input the alert title name",
285
- trigger: ["input", "blur"]
286
- }
275
+ source: {
276
+ required: true,
277
+ message: "Please input the Source",
278
+ trigger: ["input", "blur"]
279
+ },
280
+ field_names: {
281
+ required: true,
282
+ validator: validateAtLeastOne,
283
+ trigger: ["input", "blur"]
284
+ },
285
+ asset_name_array: {
286
+ required: true,
287
+ validator: validateAtLeastOneAsset,
288
+ trigger: ["input", "blur", "change"]
289
+ },
290
+ timefield_name: {
291
+ required: true,
292
+ message: "Please input the timefield name",
293
+ trigger: ["input", "blur"]
294
+ },
295
+ alert_title_name: {
296
+ required: true,
297
+ message: "Please input the alert title name",
298
+ trigger: ["input", "blur"]
299
+ }
300
}
301
302
let validationMessage: MessageReactive | null = null
303
304
const isSourceNotAllowed = computed(
292
- () => form.value.source && disabledSources.value?.length && disabledSources.value.includes(form.value.source)
305
+ () => form.value.source && disabledSources.value?.length && disabledSources.value.includes(form.value.source)
306
)
307
const isFieldEnabled = computed(
295
- () => (!!form.value.index_name && !isSourceNotAllowed.value) || arbitrarySourceField.value
308
+ () => (!!form.value.index_name && !isSourceNotAllowed.value) || arbitrarySourceField.value
309
)
310
311
const isValid = computed(() => {
299
- if (
300
- !form.value.field_names.length ||
301
- !form.value.asset_name_array?.length ||
302
- !form.value.timefield_name ||
303
- !form.value.alert_title_name ||
304
- !form.value.source ||
305
- isSourceNotAllowed.value
306
- ) {
307
- return false
308
- }
309
-
310
- return true
312
+ if (
313
+ !form.value.field_names.length ||
314
+ !form.value.asset_name_array?.length ||
315
+ !form.value.timefield_name ||
316
+ !form.value.alert_title_name ||
317
+ !form.value.source ||
318
+ isSourceNotAllowed.value
319
+ ) {
320
+ return false
321
+ }
322
+
323
+ return true
324
})
325
326
const isSocfortressRecommendsAvailable = computed(() => form.value.source?.toLowerCase() === "wazuh")
327
328
const filteredAssetNameOptions = computed(() => {
316
- return availableMappingsOptions.value.filter(
317
- option => !form.value.asset_name_array?.includes(option.value)
318
- )
329
+ return availableMappingsOptions.value.filter(option => !form.value.asset_name_array?.includes(option.value))
330
})
331
332
watch(sourceConfigurationModel, () => {
322
- reset()
323
- init()
333
+ reset()
334
+ init()
335
})
336
337
watch(
327
- () => form.value.index_name,
328
- val => {
329
- if (val) {
330
- getAvailableMappings(val)
331
- getSourceByIndex(val)
332
- } else {
333
- availableMappingsOptions.value = []
334
- }
335
- }
338
+ () => form.value.index_name,
339
+ val => {
340
+ if (val) {
341
+ getAvailableMappings(val)
342
+ getSourceByIndex(val)
343
+ } else {
344
+ availableMappingsOptions.value = []
345
+ }
346
+ }
347
)
348
349
watch(
339
- () => form.value.asset_name_array,
340
- (newVal) => {
341
- if (newVal && newVal.length > 0) {
342
- form.value.asset_name = newVal.join(", ")
343
- } else {
344
- form.value.asset_name = null
345
- }
346
- },
347
- { deep: true }
350
+ () => form.value.asset_name_array,
351
+ newVal => {
352
+ if (newVal && newVal.length > 0) {
353
+ form.value.asset_name = newVal.join(", ")
354
+ } else {
355
+ form.value.asset_name = null
356
+ }
357
+ },
358
+ { deep: true }
359
)
360
361
function renderAssetTag(tag: string, index: number) {
351
- return h(
352
- NTag,
353
- {
354
- type: index === 0 ? "primary" : "default",
355
- closable: true,
356
- onClose: () => {
357
- form.value.asset_name_array?.splice(index, 1)
358
- }
359
- },
360
- {
361
- default: () => tag,
362
- icon: () => (index === 0 ? h(Icon, { name: "carbon:star-filled", size: 14 }) : null)
363
- }
364
- )
362
+ return h(
363
+ NTag,
364
+ {
365
+ type: index === 0 ? "primary" : "default",
366
+ closable: true,
367
+ onClose: () => {
368
+ form.value.asset_name_array?.splice(index, 1)
369
+ }
370
+ },
371
+ {
372
+ default: () => tag,
373
+ icon: () => (index === 0 ? h(Icon, { name: "carbon:star-filled", size: 14 }) : null)
374
+ }
375
+ )
376
}
377
378
function handleAssetSelect(value: string, submit: (value: string) => void) {
368
- if (value && !form.value.asset_name_array?.includes(value)) {
369
- submit(value)
370
- assetNameInput.value = ""
371
- }
379
+ if (value && !form.value.asset_name_array?.includes(value)) {
380
+ submit(value)
381
+ assetNameInput.value = ""
382
+ }
383
}
384
385
function handleAssetEnter(submit: (value: string) => void) {
375
- const value = assetNameInput.value.trim()
376
- if (value && !form.value.asset_name_array?.includes(value)) {
377
- submit(value)
378
- assetNameInput.value = ""
379
- }
386
+ const value = assetNameInput.value.trim()
387
+ if (value && !form.value.asset_name_array?.includes(value)) {
388
+ submit(value)
389
+ assetNameInput.value = ""
390
+ }
391
}
392
393
function resetIndexAvailable() {
383
- form.value.index_name = null
384
- if (form.value.source) {
385
- getAvailableIndices(form.value.source)
386
- }
394
+ form.value.index_name = null
395
+ if (form.value.source) {
396
+ getAvailableIndices(form.value.source)
397
+ }
398
}
399
400
function validateAtLeastOne(_rule: FormItemRule, value: string[]) {
390
- if (!value || !value.length) {
391
- return new Error("Please select at least one option")
392
- }
401
+ if (!value || !value.length) {
402
+ return new Error("Please select at least one option")
403
+ }
404
394
- return true
405
+ return true
406
}
407
408
function validateAtLeastOneAsset(_rule: FormItemRule, value: string[]) {
398
- if (!value || !value.length) {
399
- return new Error("Please add at least one asset name field")
400
- }
401
- return true
409
+ if (!value || !value.length) {
410
+ return new Error("Please add at least one asset name field")
411
+ }
412
+ return true
413
}
414
415
function validate(cb?: () => void) {
405
- if (!formRef.value) return
406
-
407
- formRef.value.validate((errors?: Array<FormValidationError>) => {
408
- if (!errors) {
409
- validationMessage?.destroy()
410
- validationMessage = null
411
- if (cb) cb()
412
- } else {
413
- if (!validationMessage) {
414
- validationMessage = message.warning("You must fill in the required fields correctly.")
415
- }
416
- return false
417
- }
418
- })
416
+ if (!formRef.value) return
417
+
418
+ formRef.value.validate((errors?: Array<FormValidationError>) => {
419
+ if (!errors) {
420
+ validationMessage?.destroy()
421
+ validationMessage = null
422
+ if (cb) cb()
423
+ } else {
424
+ if (!validationMessage) {
425
+ validationMessage = message.warning("You must fill in the required fields correctly.")
426
+ }
427
+ return false
428
+ }
429
+ })
430
}
431
432
function getSourceConfigurationForm(): SourceConfigurationModel {
422
- const assetName = sourceConfigurationModel.value?.asset_name
423
- const assetNameArray = assetName
424
- ? assetName.split(",").map(s => s.trim()).filter(Boolean)
425
- : []
426
-
427
- return {
428
- field_names: sourceConfigurationModel.value?.field_names || [],
429
- ioc_field_names: sourceConfigurationModel.value?.ioc_field_names || [],
430
- asset_name: sourceConfigurationModel.value?.asset_name || null,
431
- asset_name_array: assetNameArray,
432
- timefield_name: sourceConfigurationModel.value?.timefield_name || null,
433
- alert_title_name: sourceConfigurationModel.value?.alert_title_name || null,
434
- source: sourceConfigurationModel.value?.source || "",
435
- index_name: sourceConfigurationModel.value?.index_name || null
436
- }
433
+ const assetName = sourceConfigurationModel.value?.asset_name
434
+ const assetNameArray = assetName
435
+ ? assetName
436
+ .split(",")
437
+ .map(s => s.trim())
438
+ .filter(Boolean)
439
+ : []
440
+
441
+ return {
442
+ field_names: sourceConfigurationModel.value?.field_names || [],
443
+ ioc_field_names: sourceConfigurationModel.value?.ioc_field_names || [],
444
+ asset_name: sourceConfigurationModel.value?.asset_name || null,
445
+ asset_name_array: assetNameArray,
446
+ timefield_name: sourceConfigurationModel.value?.timefield_name || null,
447
+ alert_title_name: sourceConfigurationModel.value?.alert_title_name || null,
448
+ source: sourceConfigurationModel.value?.source || "",
449
+ index_name: sourceConfigurationModel.value?.index_name || null
450
+ }
451
}
452
453
function reset() {
440
- if (!loading.value) {
441
- resetForm()
442
- formRef.value?.restoreValidation()
443
- }
454
+ if (!loading.value) {
455
+ resetForm()
456
+ formRef.value?.restoreValidation()
457
+ }
458
}
459
460
function resetForm() {
447
- form.value = getSourceConfigurationForm()
461
+ form.value = getSourceConfigurationForm()
462
}
463
464
function sanitizeFields() {
451
- const availableMappings = availableMappingsOptions.value.map(o => o.value)
452
-
453
- form.value.field_names = _intersection(availableMappings, form.value.field_names)
454
- form.value.ioc_field_names = _intersection(availableMappings, form.value.ioc_field_names)
455
-
456
- if (form.value.asset_name_array?.length) {
457
- form.value.asset_name_array = form.value.asset_name_array.filter(name =>
458
- availableMappings.includes(name) || arbitrarySourceField.value
459
- )
460
- }
461
-
462
- if (form.value.timefield_name && !availableMappings.includes(form.value.timefield_name)) {
463
- form.value.timefield_name = null
464
- }
465
- if (form.value.alert_title_name && !availableMappings.includes(form.value.alert_title_name)) {
466
- form.value.alert_title_name = null
467
- }
465
+ const availableMappings = availableMappingsOptions.value.map(o => o.value)
466
+
467
+ form.value.field_names = _intersection(availableMappings, form.value.field_names)
468
+ form.value.ioc_field_names = _intersection(availableMappings, form.value.ioc_field_names)
469
+
470
+ if (form.value.asset_name_array?.length) {
471
+ form.value.asset_name_array = form.value.asset_name_array.filter(
472
+ name => availableMappings.includes(name) || arbitrarySourceField.value
473
+ )
474
+ }
475
+
476
+ if (form.value.timefield_name && !availableMappings.includes(form.value.timefield_name)) {
477
+ form.value.timefield_name = null
478
+ }
479
+ if (form.value.alert_title_name && !availableMappings.includes(form.value.alert_title_name)) {
480
+ form.value.alert_title_name = null
481
+ }
482
}
483
470
-function submit() {
471
- const payload: SourceConfiguration = {
472
- field_names: form.value?.field_names || [],
473
- ioc_field_names: form.value?.ioc_field_names || [],
474
- asset_name: form.value?.asset_name || "",
475
- timefield_name: form.value?.timefield_name || "",
476
- alert_title_name: form.value?.alert_title_name || "",
477
- source: form.value?.source || ""
478
- }
479
- emit("submitted", payload)
484
+function submitForm() {
485
+ const payload: SourceConfiguration = {
486
+ field_names: form.value?.field_names || [],
487
+ ioc_field_names: form.value?.ioc_field_names || [],
488
+ asset_name: form.value?.asset_name || "",
489
+ timefield_name: form.value?.timefield_name || "",
490
+ alert_title_name: form.value?.alert_title_name || "",
491
+ source: form.value?.source || ""
492
+ }
493
+ emit("submitted", payload)
494
}
495
496
function toggleSubmittingFlag(status?: boolean) {
483
- if (status !== undefined) {
484
- submitting.value = status
485
- } else {
486
- submitting.value = !submitting.value
487
- }
497
+ if (status !== undefined) {
498
+ submitting.value = status
499
+ } else {
500
+ submitting.value = !submitting.value
501
+ }
502
489
- return submitting.value
503
+ return submitting.value
504
}
505
506
function resetSource() {
493
- form.value.source = ""
507
+ form.value.source = ""
508
}
509
510
function setSocfortressRecommendsWazuh() {
497
- form.value.field_names = socfortressRecommendsWazuh.value?.field_names || []
498
- form.value.ioc_field_names = socfortressRecommendsWazuh.value?.ioc_field_names || []
499
-
500
- const assetName = socfortressRecommendsWazuh.value?.asset_name
501
- form.value.asset_name_array = assetName
502
- ? assetName.split(",").map(s => s.trim()).filter(Boolean)
503
- : []
504
-
505
- form.value.timefield_name = socfortressRecommendsWazuh.value?.timefield_name || null
506
- form.value.alert_title_name = socfortressRecommendsWazuh.value?.alert_title_name || null
507
- form.value.source = socfortressRecommendsWazuh.value?.source || ""
511
+ form.value.field_names = socfortressRecommendsWazuh.value?.field_names || []
512
+ form.value.ioc_field_names = socfortressRecommendsWazuh.value?.ioc_field_names || []
513
+
514
+ const assetName = socfortressRecommendsWazuh.value?.asset_name
515
+ form.value.asset_name_array = assetName
516
+ ? assetName
517
+ .split(",")
518
+ .map(s => s.trim())
519
+ .filter(Boolean)
520
+ : []
521
+
522
+ form.value.timefield_name = socfortressRecommendsWazuh.value?.timefield_name || null
523
+ form.value.alert_title_name = socfortressRecommendsWazuh.value?.alert_title_name || null
524
+ form.value.source = socfortressRecommendsWazuh.value?.source || ""
525
}
526
527
function getSocfortressRecommendsWazuh() {
511
- if (socfortressRecommendsWazuh.value) {
512
- setSocfortressRecommendsWazuh()
513
- return
514
- }
515
-
516
- loadingSocfortressRecommendsWazuh.value = true
517
-
518
- Api.incidentManagement.sources
519
- .getSocfortressRecommendsWazuh()
520
- .then(res => {
521
- if (res.data.success) {
522
- socfortressRecommendsWazuh.value = {
523
- field_names: res.data.field_names,
524
- ioc_field_names: res.data.ioc_field_names,
525
- asset_name: res.data.asset_name,
526
- timefield_name: res.data.timefield_name,
527
- alert_title_name: res.data.alert_title_name,
528
- source: res.data.source
529
- }
530
-
531
- setSocfortressRecommendsWazuh()
532
- } else {
533
- message.warning(res.data?.message || "An error occurred. Please try again later.")
534
- }
535
- })
536
- .catch(err => {
537
- message.error(err.response?.data?.message || "An error occurred. Please try again later.")
538
- })
539
- .finally(() => {
540
- loadingSocfortressRecommendsWazuh.value = false
541
- })
528
+ if (socfortressRecommendsWazuh.value) {
529
+ setSocfortressRecommendsWazuh()
530
+ return
531
+ }
532
+
533
+ loadingSocfortressRecommendsWazuh.value = true
534
+
535
+ Api.incidentManagement.sources
536
+ .getSocfortressRecommendsWazuh()
537
+ .then(res => {
538
+ if (res.data.success) {
539
+ socfortressRecommendsWazuh.value = {
540
+ field_names: res.data.field_names,
541
+ ioc_field_names: res.data.ioc_field_names,
542
+ asset_name: res.data.asset_name,
543
+ timefield_name: res.data.timefield_name,
544
+ alert_title_name: res.data.alert_title_name,
545
+ source: res.data.source
546
+ }
547
+
548
+ setSocfortressRecommendsWazuh()
549
+ } else {
550
+ message.warning(res.data?.message || "An error occurred. Please try again later.")
551
+ }
552
+ })
553
+ .catch(err => {
554
+ message.error(err.response?.data?.message || "An error occurred. Please try again later.")
555
+ })
556
+ .finally(() => {
557
+ loadingSocfortressRecommendsWazuh.value = false
558
+ })
559
}
560
561
function getAvailableMappings(indexName: string) {
545
- loadingAvailableMappings.value = true
546
-
547
- Api.incidentManagement.sources
548
- .getAvailableMappings(indexName)
549
- .then(res => {
550
- if (res.data.success) {
551
- availableMappingsOptions.value = (res.data?.available_mappings || []).map(o => ({
552
- label: o,
553
- value: o
554
- }))
555
- if (applyFieldsSanitize.value) {
556
- sanitizeFields()
557
- }
558
- } else {
559
- message.warning(res.data?.message || "An error occurred. Please try again later.")
560
- }
561
- })
562
- .catch(err => {
563
- message.error(err.response?.data?.message || "An error occurred. Please try again later.")
564
- })
565
- .finally(() => {
566
- loadingAvailableMappings.value = false
567
- })
562
+ loadingAvailableMappings.value = true
563
+
564
+ Api.incidentManagement.sources
565
+ .getAvailableMappings(indexName)
566
+ .then(res => {
567
+ if (res.data.success) {
568
+ availableMappingsOptions.value = (res.data?.available_mappings || []).map(o => ({
569
+ label: o,
570
+ value: o
571
+ }))
572
+ if (applyFieldsSanitize.value) {
573
+ sanitizeFields()
574
+ }
575
+ } else {
576
+ message.warning(res.data?.message || "An error occurred. Please try again later.")
577
+ }
578
+ })
579
+ .catch(err => {
580
+ message.error(err.response?.data?.message || "An error occurred. Please try again later.")
581
+ })
582
+ .finally(() => {
583
+ loadingAvailableMappings.value = false
584
+ })
585
}
586
587
function getAvailableIndices(source: SourceName) {
571
- loadingIndexNames.value = true
572
-
573
- Api.incidentManagement.sources
574
- .getAvailableIndices(source)
575
- .then(res => {
576
- if (res.data.success) {
577
- indexNamesOptions.value = (res.data?.indices || []).map(o => ({
578
- label: o,
579
- value: o
580
- }))
581
- } else {
582
- resetSource()
583
- message.warning(res.data?.message || "An error occurred. Please try again later.")
584
- }
585
- })
586
- .catch(err => {
587
- resetSource()
588
- message.error(err.response?.data?.message || "An error occurred. Please try again later.")
589
- })
590
- .finally(() => {
591
- loadingIndexNames.value = false
592
- })
588
+ loadingIndexNames.value = true
589
+
590
+ Api.incidentManagement.sources
591
+ .getAvailableIndices(source)
592
+ .then(res => {
593
+ if (res.data.success) {
594
+ indexNamesOptions.value = (res.data?.indices || []).map(o => ({
595
+ label: o,
596
+ value: o
597
+ }))
598
+ } else {
599
+ resetSource()
600
+ message.warning(res.data?.message || "An error occurred. Please try again later.")
601
+ }
602
+ })
603
+ .catch(err => {
604
+ resetSource()
605
+ message.error(err.response?.data?.message || "An error occurred. Please try again later.")
606
+ })
607
+ .finally(() => {
608
+ loadingIndexNames.value = false
609
+ })
610
}
611
612
function getSourceByIndex(indexName: string) {
596
- loadingSource.value = true
597
-
598
- Api.incidentManagement.sources
599
- .getSourceByIndex(indexName)
600
- .then(res => {
601
- if (res.data.success) {
602
- form.value.source = res.data.source
603
- } else {
604
- resetSource()
605
- message.warning(res.data?.message || "An error occurred. Please try again later.")
606
- }
607
- })
608
- .catch(err => {
609
- resetSource()
610
- message.error(err.response?.data?.message || "An error occurred. Please try again later.")
611
- })
612
- .finally(() => {
613
- loadingSource.value = false
614
- })
613
+ loadingSource.value = true
614
+
615
+ Api.incidentManagement.sources
616
+ .getSourceByIndex(indexName)
617
+ .then(res => {
618
+ if (res.data.success) {
619
+ form.value.source = res.data.source
620
+ } else {
621
+ resetSource()
622
+ message.warning(res.data?.message || "An error occurred. Please try again later.")
623
+ }
624
+ })
625
+ .catch(err => {
626
+ resetSource()
627
+ message.error(err.response?.data?.message || "An error occurred. Please try again later.")
628
+ })
629
+ .finally(() => {
630
+ loadingSource.value = false
631
+ })
632
}
633
634
function init() {
618
- if (sourceConfigurationModel.value?.index_name) {
619
- getAvailableMappings(sourceConfigurationModel.value.index_name)
620
-
621
- if (!sourceConfigurationModel.value?.source) {
622
- getSourceByIndex(sourceConfigurationModel.value.index_name)
623
- }
624
- }
625
- if (sourceConfigurationModel.value?.source) {
626
- getAvailableIndices(sourceConfigurationModel.value.source)
627
- }
635
+ if (sourceConfigurationModel.value?.index_name) {
636
+ getAvailableMappings(sourceConfigurationModel.value.index_name)
637
+
638
+ if (!sourceConfigurationModel.value?.source) {
639
+ getSourceByIndex(sourceConfigurationModel.value.index_name)
640
+ }
641
+ }
642
+ if (sourceConfigurationModel.value?.source) {
643
+ getAvailableIndices(sourceConfigurationModel.value.source)
644
+ }
645
}
646
647
onBeforeMount(() => {
631
- init()
648
+ init()
649
})
650
651
onMounted(() => {
635
- emit("mounted", {
636
- reset,
637
- toggleSubmittingFlag
638
- })
652
+ emit("mounted", {
653
+ reset,
654
+ toggleSubmittingFlag
655
+ })
656
})
657
</script>
658
659
<style lang="scss" scoped>
660
.source-field {
644
- :deep() {
645
- .n-form-item-label__text {
646
- width: 100%;
647
- }
648
- }
661
+ :deep() {
662
+ .n-form-item-label__text {
663
+ width: 100%;
664
+ }
665
+ }
666
}
667
668
:deep(.n-dynamic-tags) {
652
- width: 100%;
669
+ width: 100%;
670
}
671
</style>