Changeset View
Changeset View
Standalone View
Standalone View
src/resources/vue/PasswordReset.vue
Show All 35 Lines | <div class="container"> | ||||
</div> | </div> | ||||
<div class="card d-none" id="step3"> | <div class="card d-none" id="step3"> | ||||
<div class="card-body"> | <div class="card-body"> | ||||
<h4 class="card-title">{{ $t('password.reset') }} - {{ $t('nav.step', { i: 3, n: 3 }) }}</h4> | <h4 class="card-title">{{ $t('password.reset') }} - {{ $t('nav.step', { i: 3, n: 3 }) }}</h4> | ||||
<p class="card-text"> | <p class="card-text"> | ||||
</p> | </p> | ||||
<form @submit.prevent="submitStep3" data-validation-prefix="reset_"> | <form @submit.prevent="submitStep3" data-validation-prefix="reset_"> | ||||
<div class="mb-3"> | <password-input class="mb-3" v-model="pass" :user="userId" v-if="userId" :focus="true"></password-input> | ||||
<label for="reset_password" class="visually-hidden">{{ $t('form.password') }}</label> | <div class="form-group pt-1 mb-3"> | ||||
<input type="password" class="form-control" id="reset_password" :placeholder="$t('form.password')" required v-model="password"> | |||||
</div> | |||||
<div class="mb-3"> | |||||
<label for="reset_confirm" class="visually-hidden">{{ $t('form.password-confirm') }}</label> | |||||
<input type="password" class="form-control" id="reset_confirm" :placeholder="$t('form.password-confirm')" required v-model="password_confirmation"> | |||||
</div> | |||||
<div class="form-group pt-3 mb-3"> | |||||
<label for="secondfactor" class="sr-only">2FA</label> | <label for="secondfactor" class="sr-only">2FA</label> | ||||
<div class="input-group"> | <div class="input-group"> | ||||
<span class="input-group-text"> | <span class="input-group-text"> | ||||
<svg-icon icon="key"></svg-icon> | <svg-icon icon="key"></svg-icon> | ||||
</span> | </span> | ||||
<input type="text" id="secondfactor" class="form-control rounded-end" placeholder="Second factor code" v-model="secondFactor"> | <input type="text" id="secondfactor" class="form-control rounded-end" placeholder="Second factor code" v-model="secondFactor"> | ||||
</div> | </div> | ||||
<small class="form-text text-muted">Second factor code is optional for users with no 2-Factor Authentication setup.</small> | <small class="form-text text-muted">Second factor code is optional for users with no 2-Factor Authentication setup.</small> | ||||
</div> | </div> | ||||
<button class="btn btn-secondary" type="button" @click="stepBack">{{ $t('btn.back') }}</button> | <button class="btn btn-secondary" type="button" @click="stepBack">{{ $t('btn.back') }}</button> | ||||
<button class="btn btn-primary ms-2" type="submit"><svg-icon icon="check"></svg-icon> {{ $t('btn.submit') }}</button> | <button class="btn btn-primary ms-2" type="submit"><svg-icon icon="check"></svg-icon> {{ $t('btn.submit') }}</button> | ||||
</form> | </form> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</template> | </template> | ||||
<script> | <script> | ||||
import PasswordInput from './Widgets/PasswordInput' | |||||
export default { | export default { | ||||
components: { | |||||
PasswordInput | |||||
}, | |||||
data() { | data() { | ||||
return { | return { | ||||
email: '', | email: '', | ||||
code: '', | code: '', | ||||
short_code: '', | short_code: '', | ||||
password: '', | pass: {}, | ||||
password_confirmation: '', | |||||
secondFactor: '', | secondFactor: '', | ||||
userId: null, | |||||
fromEmail: window.config['mail.from.address'] | fromEmail: window.config['mail.from.address'] | ||||
} | } | ||||
}, | }, | ||||
created() { | created() { | ||||
// Verification code provided, auto-submit Step 2 | // Verification code provided, auto-submit Step 2 | ||||
if (this.$route.params.code) { | if (this.$route.params.code) { | ||||
if (/^([A-Z0-9]+)-([a-zA-Z0-9]+)$/.test(this.$route.params.code)) { | if (/^([A-Z0-9]+)-([a-zA-Z0-9]+)$/.test(this.$route.params.code)) { | ||||
this.short_code = RegExp.$1 | this.short_code = RegExp.$1 | ||||
Show All 28 Lines | export default { | ||||
} | } | ||||
this.$root.clearFormValidation($('#step2 form')) | this.$root.clearFormValidation($('#step2 form')) | ||||
axios.post('/api/auth/password-reset/verify', { | axios.post('/api/auth/password-reset/verify', { | ||||
code: this.code, | code: this.code, | ||||
short_code: this.short_code | short_code: this.short_code | ||||
}).then(response => { | }).then(response => { | ||||
this.userId = response.data.userId | |||||
this.displayForm(3, true) | this.displayForm(3, true) | ||||
}).catch(error => { | }).catch(error => { | ||||
if (bylink === true) { | if (bylink === true) { | ||||
// FIXME: display step 1, user can do nothing about it anyway | // FIXME: display step 1, user can do nothing about it anyway | ||||
// Maybe we should display 404 error page? | // Maybe we should display 404 error page? | ||||
this.displayForm(1, true) | this.displayForm(1, true) | ||||
} | } | ||||
}) | }) | ||||
}, | }, | ||||
// Submits the data to the API to reset the password | // Submits the data to the API to reset the password | ||||
submitStep3() { | submitStep3() { | ||||
this.$root.clearFormValidation($('#step3 form')) | this.$root.clearFormValidation($('#step3 form')) | ||||
axios.post('/api/auth/password-reset', { | axios.post('/api/auth/password-reset', { | ||||
code: this.code, | code: this.code, | ||||
short_code: this.short_code, | short_code: this.short_code, | ||||
password: this.password, | password: this.pass.password, | ||||
password_confirmation: this.password_confirmation, | password_confirmation: this.pass.password_confirmation, | ||||
secondfactor: this.secondFactor | secondfactor: this.secondFactor | ||||
}).then(response => { | }).then(response => { | ||||
// auto-login and goto dashboard | // auto-login and goto dashboard | ||||
this.$root.loginUser(response.data) | this.$root.loginUser(response.data) | ||||
}) | }) | ||||
}, | }, | ||||
// Moves the user a step back in registration form | // Moves the user a step back in registration form | ||||
stepBack(e) { | stepBack(e) { | ||||
var card = $(e.target).closest('.card') | var card = $(e.target).closest('.card') | ||||
card.prev().removeClass('d-none').find('input').first().focus() | card.prev().removeClass('d-none').find('input').first().focus() | ||||
card.addClass('d-none').find('form')[0].reset() | card.addClass('d-none').find('form')[0].reset() | ||||
this.userId = null | |||||
}, | }, | ||||
displayForm(step, focus) { | displayForm(step, focus) { | ||||
[1, 2, 3].filter(value => value != step).forEach(value => { | [1, 2, 3].filter(value => value != step).forEach(value => { | ||||
$('#step' + value).addClass('d-none') | $('#step' + value).addClass('d-none') | ||||
}) | }) | ||||
$('#step' + step).removeClass('d-none') | $('#step' + step).removeClass('d-none') | ||||
if (focus) { | if (focus) { | ||||
$('#step' + step).find('input').first().focus() | $('#step' + step).find('input').first().focus() | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
</script> | </script> |