145 lines
3.0 KiB
Vue
145 lines
3.0 KiB
Vue
<template>
|
|
<div class="home">
|
|
<b-container v-if="ready">
|
|
<b-row>
|
|
<b-col class="total-title">
|
|
<h2>Total login attempts</h2>
|
|
</b-col>
|
|
<b-col class="total-count">
|
|
<h2>{{ totalLoginAttempts }}</h2>
|
|
</b-col>
|
|
</b-row>
|
|
<b-row>
|
|
<b-col class="total-title">
|
|
<h2>Unique passwords</h2>
|
|
</b-col>
|
|
<b-col class="total-count">
|
|
<h2>{{ uniquePasswords }}</h2>
|
|
</b-col>
|
|
</b-row>
|
|
<b-row>
|
|
<b-col class="total-title">
|
|
<h2>Unique usernames</h2>
|
|
</b-col>
|
|
<b-col class="total-count">
|
|
<h2>{{ uniqueUsernames }}</h2>
|
|
</b-col>
|
|
</b-row>
|
|
<b-row>
|
|
<b-col class="total-title">
|
|
<h2>Unique IPs</h2>
|
|
</b-col>
|
|
<b-col class="total-count">
|
|
<h2>{{ uniqueIPs }}</h2>
|
|
</b-col>
|
|
</b-row>
|
|
</b-container>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { Component, Vue, Watch } from 'vue-property-decorator';
|
|
import axios from 'axios';
|
|
|
|
type TotalStatsHeaders =
|
|
| 'UniquePasswords'
|
|
| 'UniqueUsernames'
|
|
| 'UniqueIPs'
|
|
| 'UniqueCountries'
|
|
| 'TotalLoginAttempts';
|
|
|
|
interface TotalStatsResult {
|
|
name: TotalStatsHeaders;
|
|
count: number;
|
|
}
|
|
|
|
@Component
|
|
export default class Home extends Vue {
|
|
totalLoginAttempts: number;
|
|
|
|
uniquePasswords: number;
|
|
|
|
uniqueUsernames: number;
|
|
|
|
uniqueIPs: number;
|
|
|
|
uniqueCountries: number;
|
|
|
|
private updaterHandle?: number;
|
|
|
|
ready = false;
|
|
|
|
constructor() {
|
|
super();
|
|
this.totalLoginAttempts = 0;
|
|
this.uniquePasswords = 0;
|
|
this.uniqueUsernames = 0;
|
|
this.uniqueIPs = 0;
|
|
this.uniqueCountries = 0;
|
|
}
|
|
|
|
updateStats(): void {
|
|
const url = `/api/stats?type=total`;
|
|
axios
|
|
.get<TotalStatsResult[]>(url)
|
|
.then((resp) => {
|
|
const totals = resp.data.find((e) => e.name === 'TotalLoginAttempts')
|
|
?.count;
|
|
if (totals) {
|
|
this.totalLoginAttempts = totals;
|
|
}
|
|
|
|
const passwords = resp.data.find((e) => e.name === 'UniquePasswords')
|
|
?.count;
|
|
if (passwords) {
|
|
this.uniquePasswords = passwords;
|
|
}
|
|
|
|
const usernames = resp.data.find((e) => e.name === 'UniqueUsernames')
|
|
?.count;
|
|
if (usernames) {
|
|
this.uniqueUsernames = usernames;
|
|
}
|
|
|
|
const ips = resp.data.find((e) => e.name === 'UniqueIPs')?.count;
|
|
if (ips) {
|
|
this.uniqueIPs = ips;
|
|
}
|
|
|
|
const countries = resp.data.find((e) => e.name === 'UniqueCountries')
|
|
?.count;
|
|
if (countries) {
|
|
this.uniqueCountries = countries;
|
|
}
|
|
|
|
this.ready = true;
|
|
})
|
|
.catch((e) => {
|
|
console.log(e);
|
|
});
|
|
}
|
|
|
|
created(): void {
|
|
this.updateStats();
|
|
|
|
this.updaterHandle = setInterval(() => {
|
|
this.updateStats();
|
|
}, 5000);
|
|
}
|
|
|
|
beforeDestroy(): void {
|
|
clearInterval(this.updaterHandle);
|
|
}
|
|
}
|
|
</script>
|
|
<style scoped lang="scss">
|
|
.home {
|
|
text-align: left;
|
|
}
|
|
.total-title {
|
|
text-align: right;
|
|
}
|
|
.total-count {
|
|
text-align: left;
|
|
}
|
|
</style> |