Add search
This commit is contained in:
parent
946bdd2a6a
commit
f4afd8df62
@ -2,7 +2,7 @@ package apiary
|
|||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
var Version = "v0.1.1"
|
var Version = "v0.1.2"
|
||||||
var Build string
|
var Build string
|
||||||
|
|
||||||
func FullVersion() string {
|
func FullVersion() string {
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
<b-nav-item :to="'/'">Home</b-nav-item>
|
<b-nav-item :to="'/'">Home</b-nav-item>
|
||||||
<b-nav-item :to="'/stats'">Stats</b-nav-item>
|
<b-nav-item :to="'/stats'">Stats</b-nav-item>
|
||||||
<b-nav-item :to="'/attempts'">Attempts</b-nav-item>
|
<b-nav-item :to="'/attempts'">Attempts</b-nav-item>
|
||||||
|
<b-nav-item :to="'/search'">Search</b-nav-item>
|
||||||
</b-navbar-nav>
|
</b-navbar-nav>
|
||||||
</b-collapse>
|
</b-collapse>
|
||||||
</b-navbar>
|
</b-navbar>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
hover
|
hover
|
||||||
:items="attempts"
|
:items="attempts"
|
||||||
:fields="fields"
|
:fields="fields"
|
||||||
></b-table>
|
/>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
81
web/frontend/src/components/SearchResult.vue
Normal file
81
web/frontend/src/components/SearchResult.vue
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<template>
|
||||||
|
<div class="search-result-container">
|
||||||
|
<h1>Search</h1>
|
||||||
|
<b-form @submit="onSubmit">
|
||||||
|
<b-form-input v-model="searchString" placeholder="" />
|
||||||
|
</b-form>
|
||||||
|
<b-table
|
||||||
|
class="search-results-table"
|
||||||
|
responsive="md"
|
||||||
|
striped
|
||||||
|
hover
|
||||||
|
:items="attempts"
|
||||||
|
:fields="fields"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { Component, Vue } from 'vue-property-decorator';
|
||||||
|
import { LoginAttempt } from '@/apiary/apiary';
|
||||||
|
import { BvTableFieldArray, BvTableFormatterCallback } from 'bootstrap-vue';
|
||||||
|
import Axios from 'axios';
|
||||||
|
|
||||||
|
@Component
|
||||||
|
export default class SearchResult extends Vue {
|
||||||
|
attempts: LoginAttempt[];
|
||||||
|
|
||||||
|
searchString: string;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.attempts = [];
|
||||||
|
this.searchString = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
fields: BvTableFieldArray = [
|
||||||
|
{
|
||||||
|
key: 'date',
|
||||||
|
sortable: true,
|
||||||
|
formatter: (value: string): string => {
|
||||||
|
const d = new Date(value);
|
||||||
|
// This seems stupid...
|
||||||
|
return d.toTimeString().split(' ')[0];
|
||||||
|
},
|
||||||
|
sortByFormatted: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'username',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'password',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'remoteIP',
|
||||||
|
sortable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'country',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
onSubmit(event: Event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
console.log(this.searchString);
|
||||||
|
const resp = Axios.get<LoginAttempt[]>(
|
||||||
|
`/api/query?query=${this.searchString}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
resp.then((r) => {
|
||||||
|
this.attempts = r.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.search-results-table {
|
||||||
|
margin-top: 50px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -4,6 +4,7 @@ import VueRouter, { RouteConfig } from 'vue-router';
|
|||||||
import AttemptList from '@/components/AttemptList.vue';
|
import AttemptList from '@/components/AttemptList.vue';
|
||||||
import Home from '@/components/Home.vue';
|
import Home from '@/components/Home.vue';
|
||||||
import Stats from '@/components/Stats.vue';
|
import Stats from '@/components/Stats.vue';
|
||||||
|
import SearchResult from '@/components/SearchResult.vue';
|
||||||
import 'bootstrap/dist/css/bootstrap.css';
|
import 'bootstrap/dist/css/bootstrap.css';
|
||||||
import 'bootstrap-vue/dist/bootstrap-vue.css';
|
import 'bootstrap-vue/dist/bootstrap-vue.css';
|
||||||
import '@fontsource/rubik';
|
import '@fontsource/rubik';
|
||||||
@ -38,6 +39,11 @@ const routes: Array<RouteConfig> = [
|
|||||||
name: 'Stats',
|
name: 'Stats',
|
||||||
component: Stats,
|
component: Stats,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/search',
|
||||||
|
name: 'Search',
|
||||||
|
component: SearchResult,
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const router = new VueRouter({
|
const router = new VueRouter({
|
||||||
|
@ -216,24 +216,51 @@ func (s *Server) HandlerQuery(w http.ResponseWriter, r *http.Request) {
|
|||||||
queryType := r.URL.Query().Get("type")
|
queryType := r.URL.Query().Get("type")
|
||||||
query := r.URL.Query().Get("query")
|
query := r.URL.Query().Get("query")
|
||||||
|
|
||||||
if query == "" || queryType == "" {
|
if query == "" {
|
||||||
s.WriteAPIError(w, r, http.StatusBadRequest, "Invalid query or query type")
|
s.WriteAPIError(w, r, http.StatusBadRequest, "Invalid query or query type")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
aq := store.AttemptQuery{
|
results := []models.LoginAttempt{}
|
||||||
QueryType: store.AttemptQueryType(queryType),
|
if queryType == "" {
|
||||||
|
uq := store.AttemptQuery{
|
||||||
|
QueryType: store.AttemptQueryType(store.AttemptQueryTypePassword),
|
||||||
Query: query,
|
Query: query,
|
||||||
}
|
}
|
||||||
|
pq := store.AttemptQuery{
|
||||||
results, err := s.store.Query(aq)
|
QueryType: store.AttemptQueryType(store.AttemptQueryTypeUsername),
|
||||||
|
Query: query,
|
||||||
|
}
|
||||||
|
userResults, err := s.store.Query(uq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.WriteAPIError(w, r, http.StatusInternalServerError, "Unable to perform query")
|
s.WriteAPIError(w, r, http.StatusInternalServerError, "Unable to perform query")
|
||||||
s.ServerLogger.Warnw("Error performing query", "error", err)
|
s.ServerLogger.Warnw("Error performing query", "error", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if results == nil {
|
passwordResults, err := s.store.Query(pq)
|
||||||
results = []models.LoginAttempt{}
|
if err != nil {
|
||||||
|
s.WriteAPIError(w, r, http.StatusInternalServerError, "Unable to perform query")
|
||||||
|
s.ServerLogger.Warnw("Error performing query", "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
results = append(results, userResults...)
|
||||||
|
results = append(results, passwordResults...)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
aq := store.AttemptQuery{
|
||||||
|
QueryType: store.AttemptQueryType(queryType),
|
||||||
|
Query: query,
|
||||||
|
}
|
||||||
|
|
||||||
|
queryResults, err := s.store.Query(aq)
|
||||||
|
if err != nil {
|
||||||
|
s.WriteAPIError(w, r, http.StatusInternalServerError, "Unable to perform query")
|
||||||
|
s.ServerLogger.Warnw("Error performing query", "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
results = append(results, queryResults...)
|
||||||
}
|
}
|
||||||
|
|
||||||
encoder := json.NewEncoder(w)
|
encoder := json.NewEncoder(w)
|
||||||
|
Loading…
Reference in New Issue
Block a user