misp-modules/website/app/templates/home.html

239 lines
9.1 KiB
HTML

<!--
Author: David Cruciani
-->
{% extends 'base.html' %}
{% block content %}
<div>
<header>
</header>
<h1>MISP Modules</h1>
</div>
<hr>
<br>
<div style="width:50%; transform: translate(50%, 0);">
<div>
<input type="text" id="process-query" placeholder="Enter here..." autofocus class="form-control" style="border-radius: 5px;" />
</div>
<span v-if="status_site" id="status">[[status_site]]</span>
</div>
<br>
<!-- Attributes selection -->
<div v-if="misp_attributes_list.length" style="margin-top: 10px; transform: translate(25%, 0);">
<div>
<h4>Input Attributes</h4>
</div>
<div>
<select data-placeholder="Input" class="select2-input form-control" name="input_select" id="input_select">
<option value="None">--</option>
<template v-for="attributes in misp_attributes_list">
<option :value="attributes">[[attributes]]</option>
</template>
</select>
</div>
</div>
<!-- Results modules selection -->
<template v-if="modules_list.length">
<div v-if="attr_selected.length" style="margin-top: 10px; width: 50%; transform: translate(50%, 0);">
<h4>Modules</h4>
<select data-placeholder="Modules" class="select2-modules form-control" multiple name="modules_select" id="modules_select">
<template v-for="key in modules_list">
<option v-if="key.mispattributes.input.includes(attr_selected)" :value="key.name" :title="key.meta.description">[[key.name]]</option>
</template>
</select>
</div>
</template>
<!-- Display in case a module as reauest_on_query activate -->
<div v-if="config_query.length" style="margin-top: 10px; padding: 5px" class="row">
<h4>Config</h4>
<div class="card col-4" style="margin-top: 10px; padding: 15px" v-for="module in config_query">
<h4>[[module.name]]</h4>
<div v-for="conf in module.meta.config" class="mb-3">
<label :for="'form-'+conf+'-'+module.name" class="form-label">[[conf]]</label>
<input type="text" class="form-control" :id="'form-'+conf+'-'+module.name">
<span style="color: brown;" :id="'error-'+conf+'-'+module.name"></span>
</div>
</div>
</div>
<br/>
<button class="btn btn-primary" @click="actionQuery()">Query</button>
{% endblock %}
{% block script %}
<script type="module">
const { createApp, ref, onMounted, nextTick, defineComponent} = Vue
import {message_list} from '/static/js/toaster.js'
createApp({
delimiters: ['[[', ']]'],
setup() {
const modules_list = ref([])
const misp_attributes_list = ref({})
const attr_selected = ref([])
const progress = ref(0)
const current_query = ref()
const status_site = ref()
const config_query = ref([])
async function actionQuery(){
current_query.value = $("#process-query").val()
if (!current_query.value) {
status_site.value = '↖ You need to type something'
window.scrollTo(0, 0);
return
}else{
status_site.value = ""
}
progress.value = 0
let error_flag = false
let result_dict = {"modules": $("#modules_select").val(),
"input": $("#input_select").val(),
"query": current_query.value
}
result_dict["config"] = {}
for(let el in config_query.value){
result_dict["config"][config_query.value[el].name] = {}
for(let conf in config_query.value[el].meta.config){
$("#error-"+config_query.value[el].meta.config[conf]+"-"+config_query.value[el].name).text("")
let loc = $("#form-"+config_query.value[el].meta.config[conf]+"-"+config_query.value[el].name).val()
if(!loc){
error_flag = true
$("#error-"+config_query.value[el].meta.config[conf]+"-"+config_query.value[el].name).text("Please enter value")
}else{
result_dict["config"][config_query.value[el].name][config_query.value[el].meta.config[conf]] = loc
}
}
}
if(!error_flag){
const res = await fetch('/run_modules',{
headers: { "X-CSRFToken": $("#csrf_token").val(), "Content-Type": "application/json" },
method: "POST",
body: JSON.stringify(result_dict)
})
if(await res.status == 201){
let loc = await res.json()
await nextTick()
window.location.href="/query/" + loc['id']
}else{
let loc = await res.json()
status_site.value = loc['message'] || 'Something went wrong'
if(status_site.value.includes("]")){
status_site.value = status_site.value.split("]")[1]
}
}
}
}
async function query_modules(){
let res = await fetch("/get_modules")
let loc = await res.json()
modules_list.value = loc
await query_misp_attributes()
}
query_modules()
async function query_misp_attributes(){
let res = await fetch("/get_list_misp_attributes")
let loc = await res.json()
misp_attributes_list.value = loc
await nextTick()
if (!$('.select2-input').hasClass("select2-hidden-accessible")) {
$('.select2-input').select2({
theme: 'bootstrap-5',
width: '50%'
})
}
if (!$('.select2-expansion').hasClass("select2-hidden-accessible")) {
$('.select2-expansion').select2({
theme: 'bootstrap-5'
})
}
if (!$('.select2-hover').hasClass("select2-hidden-accessible")) {
$('.select2-hover').select2({
theme: 'bootstrap-5'
})
}
$('#input_select').on('change.select2', async function (e) {
attr_selected.value = $(this).select2('data').map(item => item.id)[0]
if(attr_selected.value == 'None' ){
attr_selected.value = []
}
await nextTick()
if (!$('.select2-modules').hasClass("select2-hidden-accessible")) {
$('.select2-modules').select2({
theme: 'bootstrap-5'
})
$('#modules_select').on('change.select2', async function (e) {
let loc_list = $(this).select2('data').map(item => item.id)
config_query.value = []
for(let el in loc_list){
for(let index in modules_list.value){
if(modules_list.value[index].name == loc_list[el]){
if(modules_list.value[index].request_on_query){
config_query.value.push(modules_list.value[index])
}
break
}
}
}
})
}
})
$('#input_select').on('select2:open', function (e) {
document.querySelector('.select2-search__field').focus();
})
}
function pairedList() {
let pairs = [];
for (let i = 0; i < this.items.length; i += 2) {
pairs.push(this.items.slice(i, i + 2));
}
return pairs;
}
function checked_attr(arr1){
return arr1.includes(attr_selected.value)
}
return {
message_list,
progress,
modules_list,
misp_attributes_list,
attr_selected,
status_site,
config_query,
actionQuery,
pairedList,
checked_attr,
generateCoreFormatUI
}
}
}).mount('.container')
</script>
{% endblock %}