|
|
|
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 v-if="ready" class="coreid-auth-page-inner">
|
|
|
|
<div class="coreid-header font-weight-light">{{ app_name }}</div>
|
|
|
|
<span v-if="step === 0">
|
|
|
|
<div class="coreid-message">
|
|
|
|
{{ t['password.reset_prompt'].replace('APP_NAME', app_name) }}
|
|
|
|
<span v-if="has_mfa">
|
|
|
|
<br><br>
|
|
|
|
{{ t['password.reset_invalidates'] }}
|
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
</span>
|
|
|
|
<span v-if="step === 1">
|
|
|
|
<div class="form-group">
|
|
|
|
<label for="coreid-password-reset-input-step-1">{{ t['password.enter_new_pw'] }}</label>
|
|
|
|
<input
|
|
|
|
id="coreid-password-reset-input-step-1"
|
|
|
|
type="password"
|
|
|
|
v-model="password"
|
|
|
|
:placeholder="t['password.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">{{ t['password.calc_time'].replace('CALC_TIME', step_1_calc_time) }}</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">{{ t['password.confirm'] }}</label>
|
|
|
|
<input
|
|
|
|
id="coreid-password-reset-input-step-2"
|
|
|
|
type="password"
|
|
|
|
v-model="confirm_password"
|
|
|
|
:placeholder="t['password.confirm_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"
|
|
|
|
>{{ t['common.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 ? t['password.change'] : t['common.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 = ''
|
|
|
|
t = {}
|
|
|
|
ready = false
|
|
|
|
|
|
|
|
async vue_on_create() {
|
|
|
|
this.has_mfa = !!session.get('user.has_mfa')
|
|
|
|
|
|
|
|
this.t = await T(
|
|
|
|
'password.reset_prompt',
|
|
|
|
'password.reset_invalidates',
|
|
|
|
'password.enter_new_pw',
|
|
|
|
'password.calc_time',
|
|
|
|
'password.confirm',
|
|
|
|
'password.new_password',
|
|
|
|
'password.confirm_password',
|
|
|
|
'password.change',
|
|
|
|
'password.reset_success',
|
|
|
|
'common.unknown_error',
|
|
|
|
'common.continue',
|
|
|
|
'common.cancel'
|
|
|
|
)
|
|
|
|
|
|
|
|
this.ready = true
|
|
|
|
}
|
|
|
|
|
|
|
|
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 = this.t['password.reset_success']
|
|
|
|
await location_service.redirect('/dash/profile', 5000)
|
|
|
|
} catch (e) {
|
|
|
|
let message = this.t['common.unknown_error']
|
|
|
|
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()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|