You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
169 lines
6.1 KiB
169 lines
6.1 KiB
4 years ago
|
import { Component } from '../../lib/vues6/vues6.js'
|
||
|
import { session } from '../service/Session.service.js'
|
||
|
import { location_service } from '../service/Location.service.js'
|
||
|
import { password_service } from '../service/Password.service.js'
|
||
|
|
||
|
const template = `
|
||
|
<div class="coreid-auth-page col-lg-6 col-md-8 col-sm-10 col-xs-12 offset-lg-3 offset-md-2 offset-sm-1 offset-xs-0 text-left">
|
||
|
<div class="coreid-auth-page-inner">
|
||
|
<div class="coreid-header font-weight-light">{{ app_name }}</div>
|
||
|
<span v-if="step === 0">
|
||
|
<div class="coreid-message">
|
||
|
We're going to walk you through resetting your {{ app_name }} password.
|
||
|
<span v-if="has_mfa">
|
||
|
<br><br>
|
||
|
Note that this process will invalidate any existing app passwords you have created.
|
||
|
</span>
|
||
|
</div>
|
||
|
</span>
|
||
|
<span v-if="step === 1">
|
||
|
<div class="form-group">
|
||
|
<label for="coreid-password-reset-input-step-1">Please enter a new password for your account:</label>
|
||
|
<input
|
||
|
id="coreid-password-reset-input-step-1"
|
||
|
type="password"
|
||
|
v-model="password"
|
||
|
placeholder="New password"
|
||
|
class="form-control"
|
||
|
@keyup="on_key_up"
|
||
|
:disabled="loading"
|
||
|
name="password"
|
||
|
ref="input_1"
|
||
|
>
|
||
|
</div>
|
||
|
<div>
|
||
|
<div class="other-message" v-if="step_1_calc_time">This password would take {{ step_1_calc_time }} to crack.</div>
|
||
|
<div class="error-message" v-if="step_1_problem">{{ step_1_problem }}.</div>
|
||
|
</div>
|
||
|
</span>
|
||
|
<span v-if="step === 2">
|
||
|
<div class="form-group">
|
||
|
<label for="coreid-password-reset-input-step-1">Confirm the password:</label>
|
||
|
<input
|
||
|
id="coreid-password-reset-input-step-2"
|
||
|
type="password"
|
||
|
v-model="confirm_password"
|
||
|
placeholder="Confirm new password"
|
||
|
class="form-control"
|
||
|
@keyup="on_key_up"
|
||
|
:disabled="loading"
|
||
|
name="password_confirmation"
|
||
|
ref="input_2"
|
||
|
>
|
||
|
</div>
|
||
|
</span>
|
||
|
<div v-if="error_message" class="error-message">{{ error_message }}</div>
|
||
|
<div v-if="other_message" class="other-message">{{ other_message }}</div>
|
||
|
<div class="buttons text-right pad-top">
|
||
|
<button
|
||
|
type="button"
|
||
|
class="btn btn-primary"
|
||
|
@click="back_click"
|
||
|
:disabled="loading"
|
||
|
>Cancel</button>
|
||
|
<button
|
||
|
type="button"
|
||
|
class="btn btn-primary"
|
||
|
@click="continue_click"
|
||
|
:disabled="loading || (step === 1 && !step_1_valid) || (step === 2 && !step_2_valid)"
|
||
|
>{{ step === 2 ? 'Change Password' : 'Continue' }}</button>
|
||
|
</div>
|
||
|
<div class="coreid-loading-spinner" v-if="loading"><div class="inner"></div></div>
|
||
|
</div>
|
||
|
</div>
|
||
|
`
|
||
|
|
||
|
export default class PasswordResetComponent extends Component {
|
||
|
static get selector() { return 'coreid-password-reset-page' }
|
||
|
static get template() { return template }
|
||
|
static get props() { return ['app_name'] }
|
||
|
|
||
|
step = 0
|
||
|
loading = false
|
||
|
has_mfa = false
|
||
|
|
||
|
error_message = ''
|
||
|
other_message = ''
|
||
|
|
||
|
step_1_valid = false
|
||
|
step_1_calc_time = ''
|
||
|
step_1_problem = ''
|
||
|
|
||
|
step_2_valid = false
|
||
|
|
||
|
password = ''
|
||
|
confirm_password = ''
|
||
|
|
||
|
vue_on_create() {
|
||
|
this.has_mfa = !!session.get('user.has_mfa')
|
||
|
}
|
||
|
|
||
|
async back_click() {
|
||
|
this.loading = true
|
||
|
this.error_message = this.other_message = ''
|
||
|
if ( this.step === 0 ) {
|
||
|
await location_service.redirect('/dash/profile', 1500)
|
||
|
} else {
|
||
|
this.step -= 1
|
||
|
this.loading = false
|
||
|
}
|
||
|
}
|
||
|
|
||
|
async continue_click() {
|
||
|
this.loading = true
|
||
|
if ( this.step === 0 ) {
|
||
|
this.step += 1
|
||
|
this.error_message = this.other_message = ''
|
||
|
this.loading = false
|
||
|
this.$nextTick(() => {
|
||
|
this.$refs.input_1.focus()
|
||
|
})
|
||
|
} else if ( this.step === 1 ) {
|
||
|
if ( this.step_1_valid ) {
|
||
|
this.step += 1
|
||
|
this.error_message = this.other_message = ''
|
||
|
this.$nextTick(() => {
|
||
|
this.$refs.input_2.focus()
|
||
|
})
|
||
|
}
|
||
|
this.loading = false
|
||
|
} else if ( this.step === 2 ) {
|
||
|
if ( this.step_2_valid ) {
|
||
|
try {
|
||
|
await password_service.reset(this.password)
|
||
|
this.other_message = 'Your password was reset. For security reasons, you will be asked to sign-in again.'
|
||
|
await location_service.redirect('/dash/profile', 5000)
|
||
|
} catch (e) {
|
||
|
let message = 'An unknown error occurred while attempting to reset your password.'
|
||
|
if ( e.response && e.response.data && e.response.data.message ) {
|
||
|
message = e.response.data.message
|
||
|
}
|
||
|
|
||
|
this.error_message = message
|
||
|
this.loading = false
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this.loading = false
|
||
|
}
|
||
|
}
|
||
|
|
||
|
on_key_up(event) {
|
||
|
if ( this.step === 1 ) {
|
||
|
const result = zxcvbn(this.password)
|
||
|
this.step_1_calc_time = result.crack_times_display.offline_slow_hashing_1e4_per_second
|
||
|
this.step_1_problem = result.feedback.warning
|
||
|
this.step_1_valid = result.score >= 3 // TODO make this configurable
|
||
|
} else if ( this.step === 2 ) {
|
||
|
this.step_2_valid = this.password === this.confirm_password
|
||
|
}
|
||
|
|
||
|
if ( event.keyCode === 13 ) {
|
||
|
// Enter was pressed
|
||
|
event.preventDefault()
|
||
|
event.stopPropagation()
|
||
|
return this.continue_click()
|
||
|
}
|
||
|
}
|
||
|
}
|