Implement proper login

This commit is contained in:
Matthias 2020-05-06 21:24:12 +02:00
parent ba9240024f
commit d4d8d05c24
7 changed files with 216 additions and 30 deletions

View File

@ -6,7 +6,7 @@
<img class="logo" src="./assets/freqtrade-logo.png" alt />
Freqtrade UI
</h3>
<ul>
<ul class="navbar-nav mr-auto">
<li>
<router-link to="/" exact>Home</router-link>
</li>
@ -17,6 +17,15 @@
<router-link to="/about">About</router-link>
</li>
</ul>
<ul class="navbar-nav ">
<li class="nav-item" v-if="loggedIn">
<router-link to="/" v-on:click.native="logout()">Logout</router-link>
</li>
<li class="nav-item" v-else>
<!-- should open Modal window! -->
<router-link to="/login">login</router-link>
</li>
</ul>
</nav>
</header>
<main class="container-fluid">
@ -24,7 +33,18 @@
</main>
</div>
</template>
<script>
import { mapActions, mapState } from 'vuex';
export default {
computed: {
...mapState('user', ['loggedIn']),
},
methods: {
...mapActions('user', ['logout']),
},
};
</script>
<style scoped>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;

View File

@ -25,7 +25,15 @@ Vue.use(VueRouter)
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
},
{
path: '/login',
name: 'Login',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/Login.vue')
}
]
const router = new VueRouter({

View File

@ -3,6 +3,7 @@ import Vuex from 'vuex'
import axios from 'axios';
import ftbotModule from './modules/ftbot';
import userModule from './modules/user';
import { apiBase } from './modules/config';
@ -11,9 +12,11 @@ Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
modules: {
ftbot: ftbotModule
ftbot: ftbotModule,
user: userModule,
},
mutations: {
setPing(state, ping) {

View File

@ -1,11 +1,6 @@
const apiBase = '/api/v1'
const apiAuth = {auth: {
username: 'xxxx',
password: 'xxxx!',
}
}
const apiBase = '/api/v1';
module.exports = {
apiBase, apiAuth
apiBase
}

View File

@ -1,6 +1,6 @@
import axios from 'axios';
import { apiBase, apiAuth } from './config';
import { apiBase } from './config';
export default {
namespaced: true,
@ -13,6 +13,9 @@ export default {
botState: {},
},
getters: {
apiAuth(state, getters, rootState, rootGetters) {
return rootGetters['user/apiAuth']
},
openTrades(state) {
return state.openTrades;
// return state.trades.filter((item) => item.is_open);
@ -41,66 +44,66 @@ export default {
},
},
actions: {
getTrades({ commit }) {
getTrades({ commit, getters }) {
axios.get(`${apiBase}/trades`, {
...apiAuth
...getters.apiAuth
})
.then((result) => commit('updateTrades', result.data))
.catch(console.error);
},
getOpentrades({ commit }) {
getOpentrades({ commit, getters }) {
axios.get(`${apiBase}/status`, {
...apiAuth
...getters.apiAuth
})
.then((result) => commit('updateOpenTrades', result.data))
.catch(console.error);
},
getPerformance({commit}) {
getPerformance({ commit, getters }) {
axios.get(`${apiBase}/performance`, {
...apiAuth
...getters.apiAuth
})
.then((result) => commit('updatePerformance', result.data))
.catch(console.error);
},
getProfit({ commit }) {
getProfit({ commit, getters }) {
axios.get(`${apiBase}/profit`, {
...apiAuth
...getters.apiAuth
})
.then((result) => commit('updateProfit', result.data))
.catch(console.error);
},
getState({ commit }) {
getState({ commit, getters }) {
axios.get(`${apiBase}/show_config`, {
...apiAuth
...getters.apiAuth
})
.then((result) => commit('updateState', result.data))
.catch(console.error);
},
// Post methods
startBot() {
startBot({ getters }) {
axios.post(`${apiBase}/start`, {}, {
...apiAuth
...getters.apiAuth
})
// .then((result) => )
.catch(console.error);
},
stopBot() {
stopBot({ getters }) {
axios.post(`${apiBase}/stop`, {}, {
...apiAuth
...getters.apiAuth
})
// .then((result) => )
.catch(console.error);
},
stopBuy() {
stopBuy({ getters }) {
axios.post(`${apiBase}/stopbuy`, {}, {
...apiAuth
...getters.apiAuth
})
// .then((result) => )
.catch(console.error);
},
reloadConfig() {
reloadConfig({ getters }) {
axios.post(`${apiBase}/reload_conf`, {}, {
...apiAuth
...getters.apiAuth
})
// .then((result) => )
.catch(console.error);

54
src/store/modules/user.js Normal file
View File

@ -0,0 +1,54 @@
const userpassInit = JSON.parse(localStorage.getItem('auth'));
export default {
namespaced: true,
state: {
loggedIn: userpassInit ? 1 !== 2 : false,
},
getters: {
apiAuth() {
const userpass = JSON.parse(localStorage.getItem('auth'));
let result = {}
if (userpass) {
result = {
auth: {
username: userpass.username,
password: userpass.password,
}
};
}
else {
console.log("user not logged in");
}
return result;
},
},
mutations: {
login(state, auth) {
localStorage.setItem('auth', JSON.stringify(auth));
state.auth = auth;
state.loggedIn = true;
},
logout(state) {
console.log("Logging out")
localStorage.removeItem('auth');
state.auth = null;
state.loggedIn = false;
}
},
actions: {
login({ commit }, auth) {
commit('login', auth);
},
logout({ commit, state }) {
if (state.loggedIn) {
commit('logout');
}
else {
console.log('Not logged in');
}
}
},
};

103
src/views/Login.vue Normal file
View File

@ -0,0 +1,103 @@
<template>
<div>
<b-button v-b-modal.modal-prevent-closing>Open Modal</b-button>
<div class="mt-3">
Submitted Names:
<div v-if="submittedNames.length === 0">--</div>
<ul v-else class="mb-0 pl-3">
<li v-for="(name, index) in submittedNames" :key="index">{{ name }}</li>
</ul>
</div>
<b-modal
id="modal-prevent-closing"
ref="modal"
title="Submit Your Name"
@show="resetModal"
@hidden="resetModal"
@ok="handleOk"
>
<form ref="form" @submit.stop.prevent="handleSubmit">
<b-form-group
:state="nameState"
label="Username"
label-for="name-input"
invalid-feedback="Name is required"
>
<b-form-input
id="username-input"
v-model="auth.username"
:state="nameState"
required
></b-form-input>
</b-form-group>
<b-form-group
label="Password"
label-for="password-input"
invalid-feedback="Invalid Password"
>
<b-form-input
id="password-input"
v-model="auth.password"
required
type="password"
></b-form-input>
</b-form-group>
</form>
</b-modal>
</div>
</template>
<script>
import { mapActions } from 'vuex';
export default {
name: 'Login',
data() {
return {
auth: {
username: '',
password: '',
},
nameState: null,
submittedNames: [],
};
},
methods: {
...mapActions('user', ['login']),
checkFormValidity() {
const valid = this.$refs.form.checkValidity();
this.nameState = valid;
return valid;
},
resetModal() {
this.username = '';
this.nameState = null;
},
handleOk(bvModalEvt) {
// Prevent modal from closing
bvModalEvt.preventDefault();
// Trigger submit handler
this.handleSubmit();
},
handleSubmit() {
// Exit when the form isn't valid
if (!this.checkFormValidity()) {
return;
}
// Push the name to submitted names
this.submittedNames.push(this.auth.username);
this.login(this.auth);
// localStorage.setItem('auth', JSON.stringify(this.auth));
// Hide the modal manually
this.$nextTick(() => {
this.$bvModal.hide('modal-prevent-closing');
});
},
},
};
</script>
<style></style>