diff options
| author | Eugenij <eugenijm@protonmail.com> | 2019-09-05 11:23:28 +0000 |
|---|---|---|
| committer | Shpuld Shpludson <shp@cock.li> | 2019-09-05 11:23:28 +0000 |
| commit | 8ee5abb1a532bcfb9c70f1dad8cdeefcaf31e59c (patch) | |
| tree | 81111dad4116564279d6a1c5f2ff5921a87d31ba /src/components | |
| parent | c89703a35980f900b4d206538dc07f83e87c84d8 (diff) | |
Password reset page
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/login_form/login_form.vue | 5 | ||||
| -rw-r--r-- | src/components/password_reset/password_reset.js | 62 | ||||
| -rw-r--r-- | src/components/password_reset/password_reset.vue | 116 |
3 files changed, 183 insertions, 0 deletions
diff --git a/src/components/login_form/login_form.vue b/src/components/login_form/login_form.vue index 3ec7fe0c..b4fdcefb 100644 --- a/src/components/login_form/login_form.vue +++ b/src/components/login_form/login_form.vue @@ -33,6 +33,11 @@ type="password" > </div> + <div class="form-group"> + <router-link :to="{name: 'password-reset'}"> + {{ $t('password_reset.forgot_password') }} + </router-link> + </div> </template> <div diff --git a/src/components/password_reset/password_reset.js b/src/components/password_reset/password_reset.js new file mode 100644 index 00000000..fa71e07a --- /dev/null +++ b/src/components/password_reset/password_reset.js @@ -0,0 +1,62 @@ +import { mapState } from 'vuex' +import passwordResetApi from '../../services/new_api/password_reset.js' + +const passwordReset = { + data: () => ({ + user: { + email: '' + }, + isPending: false, + success: false, + throttled: false, + error: null + }), + computed: { + ...mapState({ + signedIn: (state) => !!state.users.currentUser, + instance: state => state.instance + }), + mailerEnabled () { + return this.instance.mailerEnabled + } + }, + created () { + if (this.signedIn) { + this.$router.push({ name: 'root' }) + } + }, + methods: { + dismissError () { + this.error = null + }, + submit () { + this.isPending = true + const email = this.user.email + const instance = this.instance.server + + passwordResetApi({ instance, email }).then(({ status }) => { + this.isPending = false + this.user.email = '' + + if (status === 204) { + this.success = true + this.error = null + } else if (status === 404 || status === 400) { + this.error = this.$t('password_reset.not_found') + this.$nextTick(() => { + this.$refs.email.focus() + }) + } else if (status === 429) { + this.throttled = true + this.error = this.$t('password_reset.too_many_requests') + } + }).catch(() => { + this.isPending = false + this.user.email = '' + this.error = this.$t('general.generic_error') + }) + } + } +} + +export default passwordReset diff --git a/src/components/password_reset/password_reset.vue b/src/components/password_reset/password_reset.vue new file mode 100644 index 00000000..00474e95 --- /dev/null +++ b/src/components/password_reset/password_reset.vue @@ -0,0 +1,116 @@ +<template> + <div class="settings panel panel-default"> + <div class="panel-heading"> + {{ $t('password_reset.password_reset') }} + </div> + <div class="panel-body"> + <form + class="password-reset-form" + @submit.prevent="submit" + > + <div class="container"> + <div v-if="!mailerEnabled"> + <p> + {{ $t('password_reset.password_reset_disabled') }} + </p> + </div> + <div v-else-if="success || throttled"> + <p v-if="success"> + {{ $t('password_reset.check_email') }} + </p> + <div class="form-group text-center"> + <router-link :to="{name: 'root'}"> + {{ $t('password_reset.return_home') }} + </router-link> + </div> + </div> + <div v-else> + <p> + {{ $t('password_reset.instruction') }} + </p> + <div class="form-group"> + <input + ref="email" + v-model="user.email" + :disabled="isPending" + :placeholder="$t('password_reset.placeholder')" + class="form-control" + type="input" + > + </div> + <div class="form-group"> + <button + :disabled="isPending" + type="submit" + class="btn btn-default btn-block" + > + {{ $t('general.submit') }} + </button> + </div> + </div> + <p + v-if="error" + class="alert error notice-dismissible" + > + <span>{{ error }}</span> + <a + class="button-icon dismiss" + @click.prevent="dismissError()" + > + <i class="icon-cancel" /> + </a> + </p> + </div> + </form> + </div> + </div> +</template> + +<script src="./password_reset.js"></script> +<style lang="scss"> +@import '../../_variables.scss'; + +.password-reset-form { + display: flex; + flex-direction: column; + align-items: center; + margin: 0.6em; + + .container { + display: flex; + flex: 1 0; + flex-direction: column; + margin-top: 0.6em; + max-width: 18rem; + } + + .form-group { + display: flex; + flex-direction: column; + margin-bottom: 1em; + padding: 0.3em 0.0em 0.3em; + line-height: 24px; + } + + .error { + text-align: center; + animation-name: shakeError; + animation-duration: 0.4s; + animation-timing-function: ease-in-out; + } + + .alert { + padding: 0.5em; + margin: 0.3em 0.0em 1em; + } + + .notice-dismissible { + padding-right: 2rem; + } + + .icon-cancel { + cursor: pointer; + } +} + +</style> |
