Реализовал ввод кредов в настройках, начал писать сетевой код

+ Получение списка сервисов
+ Получение списка стримов
* Reuse компонентов vue-router
* Шрифты в hexdump
* Прочая косметика
This commit is contained in:
saber-nyan 2019-05-04 00:03:43 +03:00
parent 6981a84e3f
commit 26643a92e3
No known key found for this signature in database
GPG Key ID: 7B069E9C295E6B4A
10 changed files with 137 additions and 23 deletions

22
package-lock.json generated
View File

@ -1917,6 +1917,15 @@
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
"dev": true
},
"axios": {
"version": "0.18.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.18.0.tgz",
"integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=",
"requires": {
"follow-redirects": "^1.3.0",
"is-buffer": "^1.1.5"
}
},
"babel-code-frame": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
@ -4880,7 +4889,6 @@
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.7.0.tgz",
"integrity": "sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==",
"dev": true,
"requires": {
"debug": "^3.2.6"
},
@ -4889,7 +4897,6 @@
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
@ -6286,8 +6293,7 @@
"is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
"dev": true
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
},
"is-callable": {
"version": "1.1.4",
@ -7225,8 +7231,7 @@
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
"dev": true
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
},
"multicast-dns": {
"version": "6.2.3",
@ -10840,6 +10845,11 @@
"integrity": "sha512-KmvZVtmM26BQOMK1rwUZsrqxEGeKiYSZGA7SNWE6uExx8UX/cj9hq2MRV/wWC3Cq6AoeDGk57rL9YMFRel/q+g==",
"dev": true
},
"vue-infinite-loading": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/vue-infinite-loading/-/vue-infinite-loading-2.4.4.tgz",
"integrity": "sha512-eIFBcyKqkivtsDDq7Ee5ybDJVGLxIzU1NcBJCHG7Zx9Ic66QEGzSPs2OPJlGUdtu0/RS7KpUER35ZP/a7FdSOg=="
},
"vue-loader": {
"version": "15.7.0",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.7.0.tgz",

View File

@ -8,11 +8,13 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"axios": "^0.18.0",
"bootstrap": "^4.3.1",
"core-js": "^2.6.5",
"jquery": "^3.4.0",
"popper.js": "^1.15.0",
"vue": "^2.6.10",
"vue-infinite-loading": "^2.4.4",
"vue-router": "^3.0.3",
"vuex": "^3.0.1",
"vuex-persistedstate": "^2.5.4"

View File

@ -10,6 +10,7 @@
<link rel="icon" type="image/png" sizes="16x16" href="<%= BASE_URL %>favicon-16x16.png">
<link rel="manifest" href="<%= BASE_URL %>site.webmanifest">
<link rel="mask-icon" href="<%= BASE_URL %>safari-pinned-tab.svg" color="#44beff">
<link href="https://fonts.googleapis.com/css?family=Ubuntu+Mono&amp;subset=cyrillic" rel="stylesheet">
<meta name="msapplication-TileColor" content="#afd9f0">
<meta name="theme-color" content="#afd9f0">

View File

@ -1,6 +1,6 @@
<template>
<div id="app">
<router-view/>
<router-view :key="$route.path"></router-view>
</div>
</template>

View File

@ -28,6 +28,11 @@ export default {
timestamp: 1556555231392,
content: 'AFDC4CVNkpxLT2ymoBJxIIKHAAACBAW0BAIICoTZHMUTHD6RAQMDBw==',
},
{
id: 41,
timestamp: 1556555231396,
content: '0KLQtdGB0YLQvtCy0LDRjyDRgdGC0YDQvtC60LAuLi4=',
},
],
}
},

View File

@ -36,19 +36,41 @@
<script>
import CtfService from "@/components/CtfService.vue";
import axios from "axios";
export default {
name: "Navbar",
data: function () {
return {
ctfServices: [
{
port: 1337,
name: 'ShittyService',
},
// {
// port: 1337,
// name: 'ShittyService',
// },
],
}
},
methods: {
getCtfServices() {
const instance = axios.create({
baseURL: this.$store.state.apiUrl,
auth: {
username: this.$store.state.apiLogin,
password: this.$store.state.apiPassword,
},
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
});
instance.get('/service/')
.then(response => (this.ctfServices = response.data))
.catch(error => console.error('Failed to load CTF services!', error))
},
},
mounted() {
this.getCtfServices();
},
components: {CtfService,},
}
</script>

View File

@ -15,7 +15,9 @@ export default {
name: 'Packet',
props: ['id', 'content', 'timestamp',],
mounted() {
new Hexdump(atob(this.$props.content), { // TODO: в настройки
// const dataString = decodeURIComponent(escape(atob(this.$props.content)));
const dataString = atob(this.$props.content);
this.hex = new Hexdump(dataString, { // TODO: в настройки
container: 'hexdump-' + this.$props.id,
base: 'hex',
width: 16,
@ -23,6 +25,7 @@ export default {
byteGrouping: 1,
html: false,
lineNumber: true,
nonPrintable: '?',
style: {
lineNumberLeft: '',
lineNumberRight: ':',
@ -31,9 +34,19 @@ export default {
hexLeft: '',
hexRight: '',
hexNull: '.g',
stringNull: '.',
stringNull: ' ',
},
});
},
beforeDestroy() {
delete this.hex;
},
}
</script>
<style scoped>
pre {
font-family: "Ubuntu Mono", "Lucida Console", monospace;
font-size: 100%;
color: black;
}
</style>

View File

@ -7,8 +7,16 @@
<label for="inputApiUrl">URL бэкенда</label>
<input type="url" class="form-control" id="inputApiUrl" placeholder="URL" v-model="apiUrl">
</div>
<div class="form-group">
<label for="inputApiLogin">Логин</label>
<input type="text" class="form-control" id="inputApiLogin" v-model="apiLogin">
</div>
<div class="form-group">
<label for="inputApiPassword">Пароль</label>
<input type="password" class="form-control" id="inputApiPassword" v-model="apiPassword">
</div>
<button type="submit" @click.prevent="$emit('close')" class="btn btn-primary">
Close
Закрыть
</button>
</form>
</div>
@ -41,6 +49,22 @@ export default {
this.$store.commit('setApiUrl', value);
},
},
apiLogin: {
get() {
return this.$store.state.apiLogin;
},
set(value) {
this.$store.commit('setApiLogin', value);
},
},
apiPassword: {
get() {
return this.$store.state.apiPassword;
},
set(value) {
this.$store.commit('setApiPassword', value);
},
},
},
}
</script>

View File

@ -6,7 +6,8 @@
v-for="stream in streams"
:key="stream.id"
:id="stream.id"
:time="stream.time"></Stream>
:time="stream.startTimestamp"></Stream>
<infinite-loading @infinite="infiniteHandler"></infinite-loading>
</ul>
</div>
</nav>
@ -14,21 +15,56 @@
<script>
import Stream from "@/components/Stream.vue";
import InfiniteLoading from "vue-infinite-loading";
import axios from "axios";
export default {
name: 'Sidebar',
props: ['servicePort', 'streamId',],
data: function () {
return {
key: this.$route.path,
streams: [
{
id: 111,
time: 1556411080,
},
// {
// id: 111,
// time: 1556411080,
// },
],
}
},
components: {Stream,},
methods: {
infiniteHandler($state) {
console.debug('getting next portion of streams...', $state);
const instance = axios.create({
baseURL: this.$store.state.apiUrl,
auth: {
username: this.$store.state.apiLogin,
password: this.$store.state.apiPassword,
},
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
});
instance.post(`/stream/${this.$props.servicePort || 'all'}`, {
fetchLatest: true,
direction: 'DESC',
startingFrom: this.streams.length,
pageSize: 50,
}).then(response => {
if (response.data[0] && this.streams[0] && response.data[0].id === this.streams[0].id) { // FIXME: проверка довольно колхозная
$state.complete();
} else {
this.streams.push(...response.data);
$state.loaded();
}
}).catch((error) => {
console.error('Failed to load new portion of streams', error);
return $state.error();
});
},
},
components: {Stream, InfiniteLoading,},
}
</script>
<style>

View File

@ -7,12 +7,13 @@ Vue.use(Vuex);
export default new Vuex.Store({
state: {
apiUrl: 'http://127.0.0.1/api',
apiLogin: 'BinaryBears',
apiPassword: '123456',
},
mutations: {
setApiUrl: (state, payload) => state.apiUrl = payload,
setApiLogin: (state, payload) => state.apiLogin = payload,
setApiPassword: (state, payload) => state.apiPassword = payload,
},
// actions: {
// setApiUrl: async (injectee, payload) => injectee.commit('setApiUrl', payload),
// },
plugins: [createPersistedState(),],
})