frequi_origin/src/components/Login.vue

209 lines
5.8 KiB
Vue
Raw Normal View History

2020-07-19 14:54:58 +00:00
<template>
<div>
2020-08-31 15:43:44 +00:00
<form ref="form" novalidate @submit.stop.prevent="handleSubmit" @reset="handleReset">
2021-08-29 11:15:41 +00:00
<b-form-group label="Bot Name" label-for="name-input">
<b-form-input
id="name-input"
v-model="auth.botName"
placeholder="Bot Name"
@keydown.enter.native="handleOk"
></b-form-input>
</b-form-group>
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
2021-11-08 05:38:00 +00:00
:state="nameState && auth.username"
2020-07-19 14:54:58 +00:00
label="Username"
label-for="username-input"
2021-11-08 05:38:00 +00:00
invalid-feedback="Name and Password are required."
2020-07-19 14:54:58 +00:00
>
<b-form-input
id="username-input"
v-model="auth.username"
required
2021-08-29 11:15:41 +00:00
placeholder="Freqtrader"
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"
2021-11-08 05:38:00 +00:00
:state="nameState && auth.password"
2020-07-19 14:54:58 +00:00
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>
<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';
2021-08-29 08:29:53 +00:00
import { Action, namespace } from 'vuex-class';
import { useUserService } from '@/shared/userService';
2020-07-19 14:54:58 +00:00
import { AuthPayload, BotDescriptor } from '@/types';
2021-08-29 08:29:53 +00:00
import { MultiBotStoreGetters } from '@/store/modules/botStoreWrapper';
2020-07-19 14:54:58 +00:00
2021-01-10 10:13:35 +00:00
const defaultURL = window.location.origin || 'http://localhost:8080';
2021-08-29 08:29:53 +00:00
const ftbot = namespace('ftbot');
2020-07-19 14:54:58 +00:00
@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
2021-08-29 08:29:53 +00:00
@ftbot.Getter [MultiBotStoreGetters.nextBotId]: string;
2021-09-26 09:06:07 +00:00
@ftbot.Getter [MultiBotStoreGetters.selectedBot]: string;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
@ftbot.Action addBot!: (payload: BotDescriptor) => void;
2021-08-29 08:29:53 +00:00
2021-09-26 09:06:07 +00:00
// eslint-disable-next-line @typescript-eslint/no-unused-vars
@ftbot.Action selectBot!: (botId: string) => void;
@Prop({ default: false }) inModal!: boolean;
2020-07-19 14:54:58 +00:00
$refs!: {
form: HTMLFormElement;
};
auth: AuthPayload = {
2021-08-29 11:15:41 +00:00
botName: '',
2020-07-19 14:54:58 +00:00
url: defaultURL,
username: '',
password: '',
};
@Emit('loginResult')
emitLoginResult(value: boolean) {
return value;
}
nameState: boolean | null = null;
urlState: boolean | null = null;
errorMessage = '';
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 = '';
2021-08-29 08:29:53 +00:00
const userService = useUserService(this.nextBotId);
2020-07-19 14:54:58 +00:00
// Push the name to submitted names
userService
.login(this.auth)
.then(() => {
2021-09-26 09:06:07 +00:00
const botId = this.nextBotId;
this.addBot({
botName: this.auth.botName,
2021-09-26 09:06:07 +00:00
botId,
2021-08-29 11:59:39 +00:00
botUrl: this.auth.url,
});
2021-09-26 09:06:07 +00:00
if (this.selectedBot === '') {
console.log(`selecting bot ${botId}`);
this.selectBot(botId);
}
2021-08-28 13:40:39 +00:00
2020-07-19 14:54:58 +00:00
this.emitLoginResult(true);
if (this.inModal === false) {
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) => {
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;
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.
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>
<style scoped lang="scss">
.alert-wrap {
white-space: pre-wrap;
}
</style>