mirror of
https://github.com/freqtrade/frequi.git
synced 2024-11-10 02:11:57 +00:00
Implement proper login
This commit is contained in:
parent
ba9240024f
commit
d4d8d05c24
22
src/App.vue
22
src/App.vue
|
@ -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;
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
const apiBase = '/api/v1'
|
||||
const apiAuth = {auth: {
|
||||
username: 'xxxx',
|
||||
password: 'xxxx!',
|
||||
}
|
||||
}
|
||||
const apiBase = '/api/v1';
|
||||
|
||||
|
||||
module.exports = {
|
||||
|
||||
apiBase, apiAuth
|
||||
apiBase
|
||||
}
|
||||
|
|
|
@ -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
54
src/store/modules/user.js
Normal 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
103
src/views/Login.vue
Normal 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>
|
Loading…
Reference in New Issue
Block a user