2020-07-19 14:54:58 +00:00
|
|
|
<template>
|
2020-12-02 07:14:00 +00:00
|
|
|
<div>
|
2020-08-31 15:43:44 +00:00
|
|
|
<form ref="form" novalidate @submit.stop.prevent="handleSubmit" @reset="handleReset">
|
2020-07-19 14:54:58 +00:00
|
|
|
<b-form-group
|
|
|
|
:state="urlState"
|
|
|
|
label="API Url"
|
|
|
|
label-for="url-input"
|
|
|
|
invalid-feedback="API Url required"
|
|
|
|
>
|
|
|
|
<b-form-input
|
|
|
|
id="url-input"
|
|
|
|
v-model="auth.url"
|
|
|
|
:state="urlState"
|
|
|
|
required
|
2020-08-31 15:43:44 +00:00
|
|
|
@keydown.enter.native="handleOk"
|
2020-07-19 14:54:58 +00:00
|
|
|
></b-form-input>
|
|
|
|
</b-form-group>
|
|
|
|
<b-form-group
|
|
|
|
:state="nameState"
|
|
|
|
label="Username"
|
|
|
|
label-for="username-input"
|
|
|
|
invalid-feedback="Name is required"
|
|
|
|
>
|
|
|
|
<b-form-input
|
|
|
|
id="username-input"
|
|
|
|
v-model="auth.username"
|
|
|
|
:state="nameState"
|
|
|
|
required
|
2020-08-31 15:43:44 +00:00
|
|
|
@keydown.enter.native="handleOk"
|
2020-07-19 14:54:58 +00:00
|
|
|
></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"
|
2020-08-31 15:43:44 +00:00
|
|
|
@keydown.enter.native="handleOk"
|
2020-07-19 14:54:58 +00:00
|
|
|
></b-form-input>
|
|
|
|
</b-form-group>
|
2020-12-02 07:14:00 +00:00
|
|
|
<div>
|
|
|
|
<b-alert v-if="errorMessage" class="alert-wrap" show variant="warning">
|
|
|
|
{{ errorMessage }}
|
|
|
|
<br />
|
|
|
|
<span v-if="errorMessageCORS">
|
|
|
|
Please also check your bot's CORS configuration:
|
|
|
|
<a href="https://www.freqtrade.io/en/latest/rest-api/#cors"
|
|
|
|
>Freqtrade CORS documentation</a
|
|
|
|
></span
|
|
|
|
>
|
|
|
|
</b-alert>
|
|
|
|
</div>
|
2020-07-19 14:54:58 +00:00
|
|
|
<div v-if="inModal === false" class="float-right">
|
|
|
|
<b-button class="mr-2" type="reset" variant="danger">Reset</b-button>
|
|
|
|
<b-button type="submit" variant="primary">Submit</b-button>
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script lang="ts">
|
|
|
|
import { Component, Vue, Emit, Prop } from 'vue-property-decorator';
|
2020-09-02 18:18:17 +00:00
|
|
|
import { Action } from 'vuex-class';
|
2020-07-19 14:54:58 +00:00
|
|
|
import userService from '@/shared/userService';
|
|
|
|
import { setBaseUrl } from '@/shared/apiService';
|
|
|
|
|
2020-08-29 09:23:39 +00:00
|
|
|
import { AuthPayload } from '@/types';
|
2020-07-19 14:54:58 +00:00
|
|
|
|
|
|
|
const defaultURL = 'http://localhost:8080';
|
|
|
|
|
|
|
|
@Component({})
|
|
|
|
export default class Login extends Vue {
|
2020-09-02 18:18:17 +00:00
|
|
|
@Action setLoggedIn;
|
2020-07-19 14:54:58 +00:00
|
|
|
|
2020-07-19 15:17:26 +00:00
|
|
|
@Prop({ default: false }) inModal!: boolean;
|
2020-07-19 14:54:58 +00:00
|
|
|
|
|
|
|
$refs!: {
|
|
|
|
form: HTMLFormElement;
|
|
|
|
};
|
|
|
|
|
|
|
|
auth: AuthPayload = {
|
|
|
|
url: defaultURL,
|
|
|
|
username: '',
|
|
|
|
password: '',
|
|
|
|
};
|
|
|
|
|
|
|
|
@Emit('loginResult')
|
|
|
|
emitLoginResult(value: boolean) {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
nameState: boolean | null = null;
|
|
|
|
|
|
|
|
urlState: boolean | null = null;
|
|
|
|
|
|
|
|
errorMessage = '';
|
|
|
|
|
2020-12-02 07:14:00 +00:00
|
|
|
errorMessageCORS = false;
|
|
|
|
|
2020-07-19 14:54:58 +00:00
|
|
|
checkFormValidity() {
|
|
|
|
const valid = this.$refs.form.checkValidity();
|
|
|
|
this.nameState = valid;
|
|
|
|
return valid;
|
|
|
|
}
|
|
|
|
|
|
|
|
resetLogin() {
|
|
|
|
this.auth.url = defaultURL;
|
|
|
|
this.auth.username = '';
|
|
|
|
this.auth.password = '';
|
|
|
|
this.nameState = null;
|
|
|
|
this.errorMessage = '';
|
|
|
|
}
|
|
|
|
|
|
|
|
handleReset(evt) {
|
|
|
|
evt.preventDefault();
|
|
|
|
this.resetLogin();
|
|
|
|
}
|
|
|
|
|
|
|
|
handleOk(evt) {
|
|
|
|
evt.preventDefault();
|
|
|
|
this.handleSubmit();
|
|
|
|
}
|
|
|
|
|
|
|
|
handleSubmit() {
|
|
|
|
// Exit when the form isn't valid
|
|
|
|
if (!this.checkFormValidity()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.errorMessage = '';
|
|
|
|
// Push the name to submitted names
|
|
|
|
userService
|
|
|
|
.login(this.auth)
|
|
|
|
.then(() => {
|
|
|
|
this.setLoggedIn(true);
|
2020-08-20 06:42:19 +00:00
|
|
|
setBaseUrl(userService.getAPIUrl());
|
2020-07-19 14:54:58 +00:00
|
|
|
this.emitLoginResult(true);
|
|
|
|
if (this.inModal === false) {
|
2020-07-19 15:17:26 +00:00
|
|
|
if (typeof this.$route.query.redirect === 'string') {
|
|
|
|
const resolved = this.$router.resolve({ path: this.$route.query.redirect });
|
|
|
|
if (resolved.route.name !== '404') {
|
|
|
|
this.$router.push(resolved.route.path);
|
|
|
|
} else {
|
|
|
|
this.$router.push('/');
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
this.$router.push('/');
|
|
|
|
}
|
2020-07-19 14:54:58 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
.catch((error) => {
|
2020-12-02 07:14:00 +00:00
|
|
|
this.errorMessageCORS = false;
|
2020-07-19 14:54:58 +00:00
|
|
|
// this.nameState = false;
|
2020-12-06 08:44:58 +00:00
|
|
|
console.error(error.response);
|
2020-07-19 14:54:58 +00:00
|
|
|
if (error.response && error.response.status === 401) {
|
|
|
|
this.nameState = false;
|
2020-12-02 07:14:00 +00:00
|
|
|
this.errorMessage = 'Connected to bot, however Login failed, Username or Password wrong.';
|
2020-07-19 14:54:58 +00:00
|
|
|
} else {
|
|
|
|
this.urlState = false;
|
|
|
|
this.errorMessage = `Login failed.
|
2020-12-02 07:14:00 +00:00
|
|
|
Please verify that the bot is running, the Bot API is enabled and the URL is reachable.
|
|
|
|
You can verify this by navigating to ${this.auth.url}/api/v1/ping to make sure the bot API is reachable`;
|
|
|
|
if (this.auth.url !== window.location.origin) {
|
|
|
|
this.errorMessageCORS = true;
|
|
|
|
}
|
2020-07-19 14:54:58 +00:00
|
|
|
}
|
2020-12-06 08:44:58 +00:00
|
|
|
console.error(this.errorMessage);
|
2020-07-19 14:54:58 +00:00
|
|
|
this.emitLoginResult(false);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
2020-12-02 07:14:00 +00:00
|
|
|
<style scoped lang="scss">
|
|
|
|
.alert-wrap {
|
|
|
|
white-space: pre-wrap;
|
|
|
|
}
|
|
|
|
</style>
|