Restructure components
This commit is contained in:
@ -1,151 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<h2 class="title has-text-centered">Login</h2>
|
||||
<div class="box">
|
||||
<div v-if="confirmedEmailSuccess" class="notification is-success has-text-centered">
|
||||
You successfully confirmed your email! You can log in now.
|
||||
</div>
|
||||
<form id="loginform" @submit.prevent="submit">
|
||||
<div class="field">
|
||||
<label class="label" for="username">Username</label>
|
||||
<div class="control">
|
||||
<input
|
||||
v-focus type="text"
|
||||
id="username"
|
||||
class="input"
|
||||
name="username"
|
||||
placeholder="e.g. frederick"
|
||||
ref="username"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="password">Password</label>
|
||||
<div class="control">
|
||||
<input
|
||||
type="password"
|
||||
class="input"
|
||||
id="password"
|
||||
name="password"
|
||||
placeholder="e.g. ••••••••••••"
|
||||
ref="password"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field" v-if="needsTotpPasscode">
|
||||
<label class="label" for="totpPasscode">Two Factor Authentication Code</label>
|
||||
<div class="control">
|
||||
<input
|
||||
type="text"
|
||||
class="input"
|
||||
id="totpPasscode"
|
||||
placeholder="e.g. 123456"
|
||||
ref="totpPasscode"
|
||||
required
|
||||
v-focus
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field is-grouped login-buttons">
|
||||
<div class="control is-expanded">
|
||||
<button type="submit" class="button is-primary" v-bind:class="{ 'is-loading': loading}">Login
|
||||
</button>
|
||||
<router-link :to="{ name: 'register' }" class="button" v-if="registrationEnabled">Register
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="control">
|
||||
<router-link :to="{ name: 'getPasswordReset' }" class="reset-password-link">Reset your
|
||||
password
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notification is-danger" v-if="errorMessage">
|
||||
{{ errorMessage }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
import router from '../../router'
|
||||
import {HTTP} from '../../http-common'
|
||||
import message from '../../message'
|
||||
import {ERROR_MESSAGE, LOADING} from '../../store/mutation-types'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
confirmedEmailSuccess: false,
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
// Try to verify the email
|
||||
// FIXME: Why is this here? Can we find a better place for this?
|
||||
let emailVerifyToken = localStorage.getItem('emailConfirmToken')
|
||||
if (emailVerifyToken) {
|
||||
const cancel = message.setLoading(this)
|
||||
HTTP.post(`user/confirm`, {token: emailVerifyToken})
|
||||
.then(() => {
|
||||
localStorage.removeItem('emailConfirmToken')
|
||||
this.confirmedEmailSuccess = true
|
||||
cancel()
|
||||
})
|
||||
.catch(e => {
|
||||
cancel()
|
||||
this.$store.commit(ERROR_MESSAGE, e.response.data.message)
|
||||
})
|
||||
}
|
||||
|
||||
// Check if the user is already logged in, if so, redirect him to the homepage
|
||||
if (this.authenticated) {
|
||||
router.push({name: 'home'})
|
||||
}
|
||||
},
|
||||
computed: mapState({
|
||||
registrationEnabled: state => state.config.registrationEnabled,
|
||||
loading: LOADING,
|
||||
errorMessage: ERROR_MESSAGE,
|
||||
needsTotpPasscode: state => state.auth.needsTotpPasscode,
|
||||
authenticated: state => state.auth.authenticated,
|
||||
}),
|
||||
methods: {
|
||||
submit() {
|
||||
this.$store.commit(ERROR_MESSAGE, '')
|
||||
// Some browsers prevent Vue bindings from working with autofilled values.
|
||||
// To work around this, we're manually getting the values here instead of relying on vue bindings.
|
||||
// For more info, see https://kolaente.dev/vikunja/frontend/issues/78
|
||||
const credentials = {
|
||||
username: this.$refs.username.value,
|
||||
password: this.$refs.password.value,
|
||||
}
|
||||
|
||||
if (this.needsTotpPasscode) {
|
||||
credentials.totpPasscode = this.$refs.totpPasscode.value
|
||||
}
|
||||
|
||||
this.$store.dispatch('auth/login', credentials)
|
||||
.then(() => {
|
||||
router.push({name: 'home'})
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.button {
|
||||
margin: 0 0.4em 0 0;
|
||||
}
|
||||
|
||||
.reset-password-link {
|
||||
display: inline-block;
|
||||
padding-top: 5px;
|
||||
}
|
||||
</style>
|
@ -1,87 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<h2 class="title has-text-centered">Reset your password</h2>
|
||||
<div class="box">
|
||||
<form id="form" @submit.prevent="submit" v-if="!successMessage">
|
||||
<div class="field">
|
||||
<label class="label" for="password1">Password</label>
|
||||
<div class="control">
|
||||
<input v-focus type="password" class="input" id="password1" name="password1" placeholder="e.g. ••••••••••••" v-model="credentials.password" required/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="password2">Retype your password</label>
|
||||
<div class="control">
|
||||
<input type="password" class="input" id="password2" name="password2" placeholder="e.g. ••••••••••••" v-model="credentials.password2" required/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field is-grouped">
|
||||
<div class="control">
|
||||
<button type="submit" class="button is-primary" :class="{ 'is-loading': this.passwordResetService.loading}">Reset your password</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notification is-info" v-if="this.passwordResetService.loading">
|
||||
Loading...
|
||||
</div>
|
||||
<div class="notification is-danger" v-if="errorMsg">
|
||||
{{ errorMsg }}
|
||||
</div>
|
||||
</form>
|
||||
<div v-if="successMessage" class="has-text-centered">
|
||||
<div class="notification is-success">
|
||||
{{ successMessage }}
|
||||
</div>
|
||||
<router-link :to="{ name: 'login' }" class="button is-primary">Login</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PasswordResetModel from '../../models/passwordReset'
|
||||
import PasswordResetService from '../../services/passwordReset'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
passwordResetService: PasswordResetService,
|
||||
credentials: {
|
||||
password: '',
|
||||
password2: '',
|
||||
},
|
||||
errorMsg: '',
|
||||
successMessage: ''
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.passwordResetService = new PasswordResetService()
|
||||
},
|
||||
methods: {
|
||||
submit() {
|
||||
this.errorMsg = ''
|
||||
|
||||
if (this.credentials.password2 !== this.credentials.password) {
|
||||
this.errorMsg = 'Passwords don\'t match'
|
||||
return
|
||||
}
|
||||
|
||||
let passwordReset = new PasswordResetModel({newPassword: this.credentials.password})
|
||||
this.passwordResetService.resetPassword(passwordReset)
|
||||
.then(response => {
|
||||
this.successMessage = response.data.message
|
||||
localStorage.removeItem('passwordResetToken')
|
||||
})
|
||||
.catch(e => {
|
||||
this.errorMsg = e.response.data.message
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.button {
|
||||
margin: 0 0.4em 0 0;
|
||||
}
|
||||
</style>
|
@ -1,102 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<h2 class="title has-text-centered">Register</h2>
|
||||
<div class="box">
|
||||
<form id="registerform" @submit.prevent="submit">
|
||||
<div class="field">
|
||||
<label class="label" for="username">Username</label>
|
||||
<div class="control">
|
||||
<input v-focus type="text" id="username" class="input" name="username" placeholder="e.g. frederick" v-model="credentials.username" required/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="email">E-mail address</label>
|
||||
<div class="control">
|
||||
<input type="email" class="input" id="email" name="email" placeholder="e.g. frederic@vikunja.io" v-model="credentials.email" required/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="password1">Password</label>
|
||||
<div class="control">
|
||||
<input type="password" class="input" id="password1" name="password1" placeholder="e.g. ••••••••••••" v-model="credentials.password" required/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="password2">Retype your password</label>
|
||||
<div class="control">
|
||||
<input type="password" class="input" id="password2" name="password2" placeholder="e.g. ••••••••••••" v-model="credentials.password2" required/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field is-grouped">
|
||||
<div class="control">
|
||||
<button type="submit" class="button is-primary" v-bind:class="{ 'is-loading': loading}">Register</button>
|
||||
<router-link :to="{ name: 'login' }" class="button">Login</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notification is-info" v-if="loading">
|
||||
Loading...
|
||||
</div>
|
||||
<div class="notification is-danger" v-if="errorMessage !== ''">
|
||||
{{ errorMessage }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import router from '../../router'
|
||||
import {mapState} from 'vuex'
|
||||
import {ERROR_MESSAGE, LOADING} from '../../store/mutation-types'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
credentials: {
|
||||
username: '',
|
||||
email: '',
|
||||
password: '',
|
||||
password2: '',
|
||||
},
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
// Check if the user is already logged in, if so, redirect him to the homepage
|
||||
if (this.authenticated) {
|
||||
router.push({name: 'home'})
|
||||
}
|
||||
},
|
||||
computed: mapState({
|
||||
authenticated: state => state.auth.authenticated,
|
||||
loading: LOADING,
|
||||
errorMessage: ERROR_MESSAGE,
|
||||
}),
|
||||
methods: {
|
||||
submit() {
|
||||
this.$store.commit(LOADING, true)
|
||||
this.$store.commit(ERROR_MESSAGE, '')
|
||||
|
||||
if (this.credentials.password2 !== this.credentials.password) {
|
||||
this.$store.commit(ERROR_MESSAGE, 'Passwords don\'t match.')
|
||||
this.$store.commit(LOADING, false)
|
||||
return
|
||||
}
|
||||
|
||||
const credentials = {
|
||||
username: this.credentials.username,
|
||||
email: this.credentials.email,
|
||||
password: this.credentials.password
|
||||
}
|
||||
|
||||
this.$store.dispatch('auth/register', credentials)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.button {
|
||||
margin: 0 0.4em 0 0;
|
||||
}
|
||||
</style>
|
@ -1,69 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<h2 class="title has-text-centered">Reset your password</h2>
|
||||
<div class="box">
|
||||
<form @submit.prevent="submit" v-if="!isSuccess">
|
||||
<div class="field">
|
||||
<label class="label" for="email">E-mail address</label>
|
||||
<div class="control">
|
||||
<input v-focus type="email" class="input" id="email" name="email" placeholder="e.g. frederic@vikunja.io" v-model="passwordReset.email" required/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field is-grouped">
|
||||
<div class="control">
|
||||
<button type="submit" class="button is-primary" v-bind:class="{ 'is-loading': passwordResetService.loading}">Send me a password reset link</button>
|
||||
<router-link :to="{ name: 'login' }" class="button">Login</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notification is-danger" v-if="errorMsg">
|
||||
{{ errorMsg }}
|
||||
</div>
|
||||
</form>
|
||||
<div v-if="isSuccess" class="has-text-centered">
|
||||
<div class="notification is-success">
|
||||
Check your inbox! You should have a mail with instructions on how to reset your password.
|
||||
</div>
|
||||
<router-link :to="{ name: 'login' }" class="button is-primary">Login</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PasswordResetModel from '../../models/passwordReset'
|
||||
import PasswordResetService from '../../services/passwordReset'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
passwordResetService: PasswordResetService,
|
||||
passwordReset: PasswordResetModel,
|
||||
errorMsg: '',
|
||||
isSuccess: false
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.passwordResetService = new PasswordResetService()
|
||||
this.passwordReset = new PasswordResetModel()
|
||||
},
|
||||
methods: {
|
||||
submit() {
|
||||
this.errorMsg = ''
|
||||
this.passwordResetService.requestResetPassword(this.passwordReset)
|
||||
.then(() => {
|
||||
this.isSuccess = true
|
||||
})
|
||||
.catch(e => {
|
||||
this.errorMsg = e.response.data.message
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.button {
|
||||
margin: 0 0.4em 0 0;
|
||||
}
|
||||
</style>
|
@ -1,313 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
class="loader-container"
|
||||
:class="{ 'is-loading': passwordUpdateService.loading || emailUpdateService.loading || totpService.loading }">
|
||||
<!-- Password update -->
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
Update Your Password
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
<form @submit.prevent="updatePassword()">
|
||||
<div class="field">
|
||||
<label class="label" for="newPassword">New Password</label>
|
||||
<div class="control">
|
||||
<input
|
||||
class="input"
|
||||
type="password"
|
||||
id="newPassword"
|
||||
placeholder="The new password..."
|
||||
v-model="passwordUpdate.newPassword"
|
||||
@keyup.enter="updatePassword"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="newPasswordConfirm">New Password Confirmation</label>
|
||||
<div class="control">
|
||||
<input
|
||||
class="input"
|
||||
type="password"
|
||||
id="newPasswordConfirm"
|
||||
placeholder="Confirm your new password..."
|
||||
v-model="passwordConfirm"
|
||||
@keyup.enter="updatePassword"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="currentPassword">Current Password</label>
|
||||
<div class="control">
|
||||
<input
|
||||
class="input"
|
||||
type="password"
|
||||
id="currentPassword"
|
||||
placeholder="Your current password"
|
||||
v-model="passwordUpdate.oldPassword"
|
||||
@keyup.enter="updatePassword"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="bigbuttons">
|
||||
<button @click="updatePassword()" class="button is-primary is-fullwidth"
|
||||
:class="{ 'is-loading': passwordUpdateService.loading}">
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Update E-Mail -->
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
Update Your E-Mail Address
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
<form @submit.prevent="updateEmail()">
|
||||
<div class="field">
|
||||
<label class="label" for="newEmail">New Email Address</label>
|
||||
<div class="control">
|
||||
<input
|
||||
class="input"
|
||||
type="email"
|
||||
id="newEmail"
|
||||
placeholder="The new email address..."
|
||||
v-model="emailUpdate.newEmail"
|
||||
@keyup.enter="updateEmail"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="currentPassword">Current Password</label>
|
||||
<div class="control">
|
||||
<input
|
||||
class="input"
|
||||
type="password"
|
||||
id="currentPassword"
|
||||
placeholder="Your current password"
|
||||
v-model="emailUpdate.password"
|
||||
@keyup.enter="updateEmail"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="bigbuttons">
|
||||
<button @click="updateEmail()" class="button is-primary is-fullwidth"
|
||||
:class="{ 'is-loading': emailUpdateService.loading}">
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- TOTP -->
|
||||
<div class="card" v-if="totpEnabled">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
Two Factor Authentication
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<a
|
||||
class="button is-primary"
|
||||
v-if="!totpEnrolled && totp.secret === ''"
|
||||
@click="totpEnroll()"
|
||||
:class="{ 'is-loading': totpService.loading }">
|
||||
Enroll
|
||||
</a>
|
||||
<div class="content" v-else-if="totp.secret !== '' && !totp.enabled">
|
||||
<p>
|
||||
To finish your setup, use this secret in your totp app (Google Authenticator or similar):
|
||||
<strong>{{ totp.secret }}</strong><br/>
|
||||
After that, enter a code from your app below.
|
||||
</p>
|
||||
<p>
|
||||
Alternatively you can scan this QR code:<br/>
|
||||
<img :src="totpQR" alt=""/>
|
||||
</p>
|
||||
<div class="field">
|
||||
<label class="label" for="totpConfirmPasscode">Passcode</label>
|
||||
<div class="control">
|
||||
<input
|
||||
class="input"
|
||||
type="text"
|
||||
id="totpConfirmPasscode"
|
||||
placeholder="A code generated by your totp application"
|
||||
v-model="totpConfirmPasscode"
|
||||
@keyup.enter="totpConfirm()"/>
|
||||
</div>
|
||||
</div>
|
||||
<a class="button is-primary" @click="totpConfirm()">Confirm</a>
|
||||
</div>
|
||||
<div class="content" v-else-if="totp.secret !== '' && totp.enabled">
|
||||
<p>
|
||||
You've sucessfully set up two factor authentication!
|
||||
</p>
|
||||
<p v-if="!totpDisableForm">
|
||||
<a class="button is-danger" @click="totpDisableForm = true">Disable</a>
|
||||
</p>
|
||||
<div v-if="totpDisableForm">
|
||||
<div class="field">
|
||||
<label class="label" for="currentPassword">Please Enter Your Password</label>
|
||||
<div class="control">
|
||||
<input
|
||||
class="input"
|
||||
type="password"
|
||||
id="currentPassword"
|
||||
placeholder="Your current password"
|
||||
v-model="totpDisablePassword"
|
||||
@keyup.enter="totpDisable"
|
||||
v-focus/>
|
||||
</div>
|
||||
</div>
|
||||
<a class="button is-danger" @click="totpDisable()">Disable two factor authentication</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card" v-if="totpEnabled">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
Migrate from other services to Vikunja
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<router-link
|
||||
class="button is-primary is-right noshadow is-outlined"
|
||||
:to="{name: 'migrateStart'}"
|
||||
v-if="migratorsEnabled"
|
||||
>
|
||||
Import your data into Vikunja
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PasswordUpdateModel from '../../models/passwordUpdate'
|
||||
import PasswordUpdateService from '../../services/passwordUpdateService'
|
||||
import EmailUpdateService from '../../services/emailUpdate'
|
||||
import EmailUpdateModel from '../../models/emailUpdate'
|
||||
import TotpModel from '../../models/totp'
|
||||
import TotpService from '../../services/totp'
|
||||
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'Settings',
|
||||
data() {
|
||||
return {
|
||||
passwordUpdateService: PasswordUpdateService,
|
||||
passwordUpdate: PasswordUpdateModel,
|
||||
passwordConfirm: '',
|
||||
|
||||
emailUpdateService: EmailUpdateService,
|
||||
emailUpdate: EmailUpdateModel,
|
||||
|
||||
totpService: TotpService,
|
||||
totp: TotpModel,
|
||||
totpQR: '',
|
||||
totpEnrolled: false,
|
||||
totpConfirmPasscode: '',
|
||||
totpDisableForm: false,
|
||||
totpDisablePassword: '',
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.passwordUpdateService = new PasswordUpdateService()
|
||||
this.passwordUpdate = new PasswordUpdateModel()
|
||||
|
||||
this.emailUpdateService = new EmailUpdateService()
|
||||
this.emailUpdate = new EmailUpdateModel()
|
||||
|
||||
this.totpService = new TotpService()
|
||||
this.totp = new TotpModel()
|
||||
|
||||
this.totpStatus()
|
||||
},
|
||||
computed: mapState({
|
||||
totpEnabled: state => state.config.totpEnabled,
|
||||
migratorsEnabled: state => state.config.availableMigrators !== null && state.config.availableMigrators.length > 0,
|
||||
}),
|
||||
methods: {
|
||||
updatePassword() {
|
||||
if (this.passwordConfirm !== this.passwordUpdate.newPassword) {
|
||||
this.error({message: 'The new password and its confirmation don\'t match.'}, this)
|
||||
return
|
||||
}
|
||||
|
||||
this.passwordUpdateService.update(this.passwordUpdate)
|
||||
.then(() => {
|
||||
this.success({message: 'The password was successfully updated.'}, this)
|
||||
})
|
||||
.catch(e => this.error(e, this))
|
||||
},
|
||||
updateEmail() {
|
||||
this.emailUpdateService.update(this.emailUpdate)
|
||||
.then(() => {
|
||||
this.success({message: 'Your email address was successfully updated. We\'ve sent you a link to confirm it.'}, this)
|
||||
})
|
||||
.catch(e => this.error(e, this))
|
||||
},
|
||||
totpStatus() {
|
||||
if (!this.totpEnabled) {
|
||||
return
|
||||
}
|
||||
this.totpService.get()
|
||||
.then(r => {
|
||||
this.$set(this, 'totp', r)
|
||||
this.totpSetQrCode()
|
||||
})
|
||||
.catch(e => {
|
||||
// Error code 1016 means totp is not enabled, we don't need an error in that case.
|
||||
if (e.response && e.response.data && e.response.data.code && e.response.data.code === 1016) {
|
||||
this.totpEnrolled = false
|
||||
return
|
||||
}
|
||||
|
||||
this.error(e, this)
|
||||
})
|
||||
},
|
||||
totpSetQrCode() {
|
||||
this.totpService.qrcode()
|
||||
.then(qr => {
|
||||
const urlCreator = window.URL || window.webkitURL
|
||||
this.totpQR = urlCreator.createObjectURL(qr)
|
||||
})
|
||||
},
|
||||
totpEnroll() {
|
||||
this.totpService.enroll()
|
||||
.then(r => {
|
||||
this.totpEnrolled = true
|
||||
this.$set(this, 'totp', r)
|
||||
this.totpSetQrCode()
|
||||
})
|
||||
.catch(e => this.error(e, this))
|
||||
},
|
||||
totpConfirm() {
|
||||
this.totpService.enable({passcode: this.totpConfirmPasscode})
|
||||
.then(() => {
|
||||
this.$set(this.totp, 'enabled', true)
|
||||
this.success({message: 'You\'ve successfully confirmed your totp setup and can use it from now on!'}, this)
|
||||
})
|
||||
.catch(e => this.error(e, this))
|
||||
},
|
||||
totpDisable() {
|
||||
this.totpService.disable({password: this.totpDisablePassword})
|
||||
.then(() => {
|
||||
this.totpEnrolled = false
|
||||
this.$set(this, 'totp', new TotpModel())
|
||||
this.success({message: 'Two factor authentication was sucessfully disabled.'}, this)
|
||||
})
|
||||
.catch(e => this.error(e, this))
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
Reference in New Issue
Block a user