main
vue 153 lines 3.28 KB
Raw
1 <template>
2 <n-spin :show="loading" class="creation-report-form">
3 <n-form ref="formRef" :label-width="80" :model="form" :rules>
4 <div class="flex flex-col gap-2">
5 <div class="flex items-start gap-4">
6 <n-form-item label="Host" path="host" class="grow">
7 <n-input v-model:value.trim="form.host" placeholder="Please insert the Host" clearable />
8 </n-form-item>
9 </div>
10
11 <div class="flex justify-between gap-4">
12 <n-button :disabled="loading" @click="reset()">Reset</n-button>
13 <n-button
14 type="primary"
15 :disabled="!isValid"
16 :loading="submitting"
17 @click="validate(() => submit())"
18 >
19 Submit
20 </n-button>
21 </div>
22 </div>
23 </n-form>
24 </n-spin>
25 </template>
26
27 <script setup lang="ts">
28 import type { FormInst, FormItemRule, FormRules, FormValidationError, MessageReactive } from "naive-ui"
29 import type { ScanHostPayload } from "@/types/webVulnerabilityAssessment.d"
30 import { NButton, NForm, NFormItem, NInput, NSpin, useMessage } from "naive-ui"
31 import isURL from "validator/es/lib/isURL"
32 import { computed, onMounted, ref } from "vue"
33 import Api from "@/api"
34
35 type FormPayload = ScanHostPayload
36
37 const emit = defineEmits<{
38 (e: "submitted"): void
39 (
40 e: "mounted",
41 value: {
42 reset: () => void
43 }
44 ): void
45 }>()
46
47 const submitting = ref(false)
48 const loading = computed(() => submitting.value)
49 const message = useMessage()
50 const form = ref<FormPayload>(getClearForm())
51 const formRef = ref<FormInst | null>(null)
52
53 function validateUrl(_rule: FormItemRule, value: string) {
54 if (!value) {
55 return new Error("Please input a valid Host")
56 }
57 if (!isURL(value, { require_tld: false })) {
58 return new Error("Please input a valid Host")
59 }
60
61 return true
62 }
63
64 const rules: FormRules = {
65 host: {
66 required: true,
67 validator: validateUrl,
68 trigger: "blur"
69 }
70 }
71
72 let validationMessage: MessageReactive | null = null
73
74 const isValid = computed(() => {
75 if (!form.value.host) {
76 return false
77 }
78
79 return true
80 })
81
82 function validate(cb?: () => void) {
83 if (!formRef.value) return
84
85 formRef.value.validate((errors?: Array<FormValidationError>) => {
86 if (!errors) {
87 validationMessage?.destroy()
88 validationMessage = null
89 if (cb) cb()
90 } else {
91 if (!validationMessage) {
92 validationMessage = message.warning("You must fill in the required fields correctly.")
93 }
94 return false
95 }
96 })
97 }
98
99 function getClearForm(): FormPayload {
100 return {
101 host: ""
102 }
103 }
104
105 function reset() {
106 if (!loading.value) {
107 resetForm()
108 formRef.value?.restoreValidation()
109 }
110 }
111
112 function resetForm() {
113 form.value = getClearForm()
114 }
115
116 function submit() {
117 submitting.value = true
118
119 const payload: ScanHostPayload = {
120 ...form.value
121 }
122
123 Api.webVulnerabilityAssessment
124 .scan(payload)
125 .then(res => {
126 if (res.data.success) {
127 message.success(
128 res.data?.message ||
129 `Scan started for ${payload.host}. This will take some time to complete, but check back in soon.`,
130 {
131 duration: 10 * 1000
132 }
133 )
134 emit("submitted")
135 resetForm()
136 } else {
137 message.warning(res.data?.message || "An error occurred. Please try again later.")
138 }
139 })
140 .catch(err => {
141 message.error(err.response?.data?.message || "An error occurred. Please try again later.")
142 })
143 .finally(() => {
144 submitting.value = false
145 })
146 }
147
148 onMounted(() => {
149 emit("mounted", {
150 reset
151 })
152 })
153 </script>