Break out components, add compare feature

This commit is contained in:
Evan Reichard 2021-03-21 17:58:12 -04:00
parent 6b40111a3b
commit b0b9a4d0d0
13 changed files with 179 additions and 66 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/static/favicon.ico"><title>Overseer</title><link href="/static/css/app.adf7b5c2.css" rel="preload" as="style"><link href="/static/js/app.a3974328.js" rel="preload" as="script"><link href="/static/js/chunk-vendors.4fdbc4a4.js" rel="preload" as="script"><link href="/static/css/app.adf7b5c2.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but Overseer doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="/static/js/chunk-vendors.4fdbc4a4.js"></script><script src="/static/js/app.a3974328.js"></script></body></html> <!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/static/favicon.ico"><title>Overseer</title><link href="/static/css/app.107f39c9.css" rel="preload" as="style"><link href="/static/js/app.fbd98594.js" rel="preload" as="script"><link href="/static/js/chunk-vendors.1f751c93.js" rel="preload" as="script"><link href="/static/css/app.107f39c9.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but Overseer doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="/static/js/chunk-vendors.1f751c93.js"></script><script src="/static/js/app.fbd98594.js"></script></body></html>

View File

@ -0,0 +1,56 @@
<template>
<ul>
<li v-for="port in ports" :key="port" v-bind:style="getItemWidth()">
<span>{{ port.split(" ")[0] }}</span>
<span class="proto" v-bind:style="dynamicProtocolStyle(port.split(' ')[1])" >{{ port.split(" ")[1] }}</span>
</li>
</ul>
</template>
<script>
export default {
name: 'PortList',
props: ["ports", "itemWidth"],
methods: {
dynamicProtocolStyle(proto) {
return {
backgroundColor: proto == "TCP" ? "#E7E6FF" : "#D5EFFF",
}
},
getItemWidth() {
return {
width: this.itemWidth || "75px"
}
}
}
}
</script>
<style scoped>
.proto {
border-radius: 4px;
padding: 0px 2px;
color: #0A282F;
margin-left: 5px;
}
li {
display: flex;
margin: 10px 43px;
width: 75px;
}
li span {
font-weight: 700;
}
ul {
display: flex;
column-count: 3;
flex-wrap: wrap;
flex-direction: row;
list-style-type: none;
padding: 0px;
margin: 0px;
}
</style>

View File

@ -0,0 +1,40 @@
<template>
<div>
<div v-if="getPortDiff(newScan, oldScan).length + getPortDiff(oldScan, newScan).length == 0">
<h4>No Differences Found</h4>
</div>
<div v-if="getPortDiff(newScan, oldScan).length > 0">
<h4 style="text-decoration: underline;">New Ports</h4>
<PortList :ports="getPortDiff(newScan, oldScan)" itemWidth="70px" />
</div>
<div v-if="getPortDiff(oldScan, newScan).length > 0">
<h4 style="text-decoration: underline;">Removed Ports</h4>
<PortList :ports="getPortDiff(oldScan, newScan)" itemWidth="70px" />
</div>
</div>
</template>
<script>
import PortList from '../components/PortList.vue'
export default {
name: 'ScanCompare',
props: ["newScan", "oldScan"],
components: {
PortList,
},
methods: {
getPortDiff(s1, s2) {
return s1.results
.filter(p => !s2.results.includes(p));
},
}
}
</script>
<style scoped>
h4 {
margin: 10px 0px;
text-align: center;
}
</style>

View File

@ -11,8 +11,10 @@
<h2 id="scan-status">No Scans Found</h2> <h2 id="scan-status">No Scans Found</h2>
</div> </div>
<div v-else> <div v-else>
<h2 v-if="scan.status == 'IN_PROGRESS'" id="scan-status">Scanning in Progress</h2> <router-link :to="`/scan/${scan.target}/${scan.id}`" style="text-decoration: none;">
<h2 v-else id="scan-status">Scan Results</h2> <h2 v-if="scan.status == 'IN_PROGRESS'" id="scan-status">Scanning in Progress</h2>
<h2 v-else id="scan-status">Scan Result</h2>
</router-link>
<h5 id="sub-status">{{ normalizeDate(scan.created_at) }}</h5> <h5 id="sub-status">{{ normalizeDate(scan.created_at) }}</h5>
@ -22,17 +24,13 @@
<ScanProgress title="Total" :percentage="scan.total_progress" /> <ScanProgress title="Total" :percentage="scan.total_progress" />
</div> </div>
<ul> <PortList :ports="scan.results"/>
<li v-for="port in scan.results" :key="port">
<span>{{ port.split(" ")[0] }}</span>
<span class="proto" v-bind:style="dynamicProtocolStyle(port.split(' ')[1])" >{{ port.split(" ")[1] }}</span>
</li>
</ul>
</div> </div>
</template> </template>
<script> <script>
import Loading from '../components/Loading.vue' import Loading from '../components/Loading.vue'
import PortList from '../components/PortList.vue'
import ScanProgress from '../components/ScanProgress.vue' import ScanProgress from '../components/ScanProgress.vue'
export default { export default {
@ -40,18 +38,14 @@ export default {
props: ["scan", "error", "loading"], props: ["scan", "error", "loading"],
components: { components: {
Loading, Loading,
PortList,
ScanProgress, ScanProgress,
}, },
methods: { methods: {
normalizeDate(dateISO) { normalizeDate(dateISO) {
let parsedDate = new Date(dateISO); let parsedDate = new Date(dateISO);
return parsedDate.toDateString() + " " + parsedDate.toLocaleTimeString() return parsedDate.toDateString() + " " + parsedDate.toLocaleTimeString()
}, }
dynamicProtocolStyle(proto) {
return {
"backgroundColor": proto == "TCP" ? "#E7E6FF" : "#D5EFFF",
}
},
} }
} }
</script> </script>
@ -60,19 +54,13 @@ export default {
#scan-status { #scan-status {
color: #EAECE9; color: #EAECE9;
text-align: center; text-align: center;
margin: 0px;
} }
#sub-status { #sub-status {
text-align: center; text-align: center;
width: 100%; width: 200px;
margin: -20px 0px 10px 0px; margin: -5px auto 10px auto;
border-bottom: 1px solid; border-bottom: 1px solid;
} }
.proto {
border-radius: 4px;
padding: 0px 2px;
color: #0A282F;
margin-left: 5px;
}
</style> </style>

View File

@ -1,29 +1,63 @@
<template> <template>
<div id="overseer-scan" style="padding: 50px;"> <div id="overseer-scan" style="padding: 50px;">
<h1 style="font-size: 2.5em; margin: 0px; float: left;">{{ $route.params.target }}</h1> <router-link :to="`/scan/${$route.params.target}`">
<span v-if="getRequestedScan.status == 'COMPLETE'" v-on:click="performScan()" id="scan-button">Scan Again</span> <h1 style="font-size: 2.5em; margin: 0px; float: left; color: #EAECE9">{{ $route.params.target }}</h1>
</router-link>
<span v-if="getRequestedScans[0].status == 'COMPLETE'" v-on:click="performScan()" id="scan-button">Scan Again</span>
<div id="results"> <div id="results">
<ScanResult :scan="getRequestedScan" :error="error" :loading="loading"/> <div v-for="(scan, index) in getRequestedScans" :key= "scan.id">
<ScanResult
:scan="scan"
:error="error"
:loading="loading"
style="padding: 20px; margin-top: 25px; border-radius: 5px; box-shadow: 0px 0px 10px #e0e3de;"/>
<div ref="compareContainer"
v-if="getRequestedScans.length != index + 1"
v-bind:style="deriveCompareStyle(scan)"
v-on:click="toggleCompare(scan)" class="compare-content">
<h4 v-if="!openCompare.includes(scan)" style="margin: 0px; text-align: center;">Compare</h4>
<ScanCompare v-else :newScan="scan" :oldScan="getRequestedScans[index + 1]" />
</div>
</div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import ScanResult from '../components/ScanResult.vue' import ScanResult from '../components/ScanResult.vue'
import ScanCompare from '../components/ScanCompare.vue'
export default { export default {
name: 'Scan', name: 'Scan',
components: { components: {
ScanResult, ScanResult,
ScanCompare,
}, },
data() { data() {
return { return {
error: null, error: null,
loading: false loading: false,
openCompare: []
} }
}, },
methods: { methods: {
deriveCompareStyle(scan) {
if (!this.openCompare.includes(scan))
return {};
return {
"width": "90%",
"padding": "10px",
"max-height": "10000px",
}
},
toggleCompare(scan) {
if (this.openCompare.includes(scan))
this.openCompare = this.openCompare
.filter(item => item !== scan)
else
this.openCompare.push(scan);
},
performScan() { performScan() {
this.error = null; this.error = null;
this.loading = true; this.loading = true;
@ -32,28 +66,29 @@ export default {
.then(scan => { .then(scan => {
if (scan.error) if (scan.error)
throw new Error(scan.error) throw new Error(scan.error)
this.$router.push({ path: `/scan/${this.$route.params.target}/${scan.id}` }) this.$router.push({ path: `/scan/${this.$route.params.target}` })
// this.$router.push({ path: `/scan/${this.$route.params.target}/${scan.id}` })
}).catch(err => { }).catch(err => {
this.error = err; this.error = err;
}).finally(() => { }).finally(() => {
this.loading = false; this.loading = false;
}); });
} },
}, },
computed: { computed: {
getRequestedScan() { getRequestedScans() {
let scanCache = this.$store.state.scan_cache; let scanCache = this.$store.state.scan_cache;
let target = this.$route.params.target; let target = this.$route.params.target;
let scanID = this.$route.params.scan_id; let scanID = this.$route.params.scan_id;
if (!scanCache[target]) if (!scanCache[target])
return { "status": "LOADING" } return [{ "status": "LOADING" }]
if (scanID) if (scanID)
return scanCache[target] return scanCache[target]
.find(item => item.id == scanID) || { "status": "NO_RESULTS" }; .filter(item => item.id == scanID) || [{ "status": "NO_RESULTS" }];
else else
return scanCache[target][0] || { "status": "NO_RESULTS" }; return scanCache[target] || [{ "status": "NO_RESULTS" }];
} }
}, },
mounted(){ mounted(){
@ -68,29 +103,10 @@ export default {
} }
#results { #results {
width: 500px; width: 700px;
margin: 150px auto 0px auto; margin: 150px auto 0px auto;
} }
li {
display: flex;
margin: 10px 43px;
width: 80px;
}
li span {
font-weight: 700;
}
ul {
display: flex;
column-count: 3;
flex-wrap: wrap;
flex-direction: row;
list-style-type: none;
padding: 0px;
}
#scan-button { #scan-button {
font-size: 1em; font-size: 1em;
background-color: #0E6A0E; background-color: #0E6A0E;
@ -101,4 +117,17 @@ ul {
cursor: pointer; cursor: pointer;
margin: 8px; margin: 8px;
} }
.compare-content {
width: 70px;
max-height: 22px;
padding: 0px 10px;
background-color: #C9582C;
border-radius: 15px;
transition: 0.5s;
font-weight: 700;
margin: 25px auto 0px auto;
overflow: hidden;
cursor: pointer;
}
</style> </style>