From 0029313775fb294b488ebfd809c88d1ace7eea94 Mon Sep 17 00:00:00 2001 From: raeno Date: Wed, 5 Dec 2018 13:43:01 +0400 Subject: Add client validation for registration form * also extract registration logic to users.js module --- src/modules/users.js | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) (limited to 'src/modules/users.js') diff --git a/src/modules/users.js b/src/modules/users.js index 8630ee0d..572a62c6 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -1,6 +1,9 @@ import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js' import { compact, map, each, merge } from 'lodash' import { set } from 'vue' +import { SIGN_UP } from '../mutation_types' +import oauthApi from '../services/new_api/oauth' +import {humanizeErrors} from './errors' // TODO: Unify with mergeOrAdd in statuses.js export const mergeOrAdd = (arr, obj, item) => { @@ -46,15 +49,26 @@ export const mutations = { setColor (state, { user: {id}, highlighted }) { const user = state.usersObject[id] set(user, 'highlight', highlighted) + }, + [SIGN_UP.PENDING] (state) { + state[SIGN_UP.isPending] = true + }, + [SIGN_UP.SUCCESS] (state) { + state[SIGN_UP.isPending] = false + }, + [SIGN_UP.FAILURE] (state, errors) { + state[SIGN_UP.isPending] = false + state[SIGN_UP.errors] = [...state[SIGN_UP.errors], ...errors] } } export const defaultState = { lastLoginName: false, currentUser: false, - loggingIn: false, users: [], - usersObject: {} + usersObject: {}, + sign_up_pending: false, + sign_up_errors: [] } const users = { @@ -80,6 +94,32 @@ const users = { store.commit('setUserForStatus', status) }) }, + async signUp (store, userInfo) { + store.commit(SIGN_UP.PENDING) + + let response = await store.rootState.api.backendInteractor.register(userInfo) + if (response.ok) { + const data = { + oauth: store.state.oauth, + instance: store.state.instance.server + } + let app = await oauthApi.getOrCreateApp(data) + let result = await oauthApi.getTokenWithCredentials({ + app, + instance: data.instance, + username: this.user.username, + password: this.user.password + }) + store.commit(SIGN_UP.SUCCESS) + store.commit('setToken', result.access_token) + store.dispatch('loginUser', result.access_token) + this.$router.push('/main/friends') + } else { + let data = await response.json() + let errors = humanizeErrors(JSON.parse(data.error)) + store.commit(SIGN_UP.FAILURE, errors) + } + }, logout (store) { store.commit('clearCurrentUser') store.commit('setToken', false) -- cgit v1.2.3-70-g09d2 From f9ff839b1af7cdae2bc9ff5090844ea6b1fac6ac Mon Sep 17 00:00:00 2001 From: raeno Date: Wed, 5 Dec 2018 19:17:29 +0400 Subject: Better styling for client-side validation. Add I18n for validation errors. --- src/components/registration/registration.js | 30 +++++++++++++------- src/components/registration/registration.vue | 41 +++++++++++++++++++++++++--- src/i18n/en.json | 10 ++++++- src/i18n/ru.json | 10 ++++++- src/modules/users.js | 17 +++++++----- 5 files changed, 85 insertions(+), 23 deletions(-) (limited to 'src/modules/users.js') diff --git a/src/components/registration/registration.js b/src/components/registration/registration.js index 69474585..67c052f1 100644 --- a/src/components/registration/registration.js +++ b/src/components/registration/registration.js @@ -1,5 +1,5 @@ import { validationMixin } from 'vuelidate' -import { required } from 'vuelidate/lib/validators' +import { required, sameAs, email } from 'vuelidate/lib/validators' import { mapActions, mapState } from 'vuex' import { SIGN_UP } from '../../mutation_types' @@ -16,24 +16,29 @@ const registration = { }), validations: { user: { - email: { required }, + email: { required, email }, username: { required }, password: { required }, - confirm: { required } + confirm: { + required, + sameAsPassword: sameAs('password') + } } }, created () { - if ((!this.$store.state.instance.registrationOpen && !this.token) || !!this.$store.state.users.currentUser) { + if ((!this.registrationOpen && !this.token) || this.signedIn) { this.$router.push('/main/all') } - // Seems like this doesn't work at first page open for some reason - if (this.$store.state.instance.registrationOpen && this.token) { - this.$router.push('/registration') - } + // // Seems like this doesn't work at first page open for some reason + // if (this.$store.state.instance.registrationOpen && this.token) { + // this.$router.push('/registration') + // } }, computed: { token () { return this.$route.params.token }, ...mapState({ + registrationOpen: (state) => state.instance.registrationOpen, + signedIn: (state) => !!state.users.currentUser, isPending: (state) => state.users[SIGN_UP.isPending], serverValidationErrors: (state) => state.users[SIGN_UP.errors], termsofservice: (state) => state.instance.tos @@ -41,14 +46,19 @@ const registration = { }, methods: { ...mapActions(['signUp']), - submit () { + async submit () { this.user.nickname = this.user.username this.user.token = this.token this.$v.$touch() if (!this.$v.$invalid) { - this.signUp(this.user) + try { + await this.signUp(this.user) + this.$router.push('/main/friends') + } catch (error) { + console.log("Registration failed: " + error) + } } } } diff --git a/src/components/registration/registration.vue b/src/components/registration/registration.vue index 73200990..5f6357a2 100644 --- a/src/components/registration/registration.vue +++ b/src/components/registration/registration.vue @@ -12,7 +12,11 @@
- Username is required. +
    +
  • + {{$t('registration.validations.username_required')}} +
  • +
@@ -25,7 +29,14 @@
- Email is required. +
    +
  • + {{$t('registration.validations.email_required')}} +
  • +
  • + {{$t('registration.validations.email_valid')}} +
  • +
@@ -38,7 +49,11 @@
- Password is required. +
    +
  • + {{$t('registration.validations.password_required')}} +
  • +
@@ -46,7 +61,14 @@
- Password confirmation is required. +
    +
  • + {{$t('registration.validations.password_confirmation_required')}} +
  • +
  • + {{$t('registration.validations.password_confirmation_match')}} +
  • +