DEV Community

Tobias Mesquita for Quasar Framework Brasil

Posted on

QPANC - Parte 17 - Quasar - Registro

QPANC são as iniciais de Quasar PostgreSQL ASP NET Core.

35 Registrar Usuário.

Antes de criamos o componente de registro, precisamos adicionar duas novas regras de validação no validations.js

QPANC.App/src/services/validations.js

validations.compare = ({ self, field }) => {
  return function required (val) {
    var other = self.validationArgs[field].compare
    return val === self[other] || self.$t('validations.compare', {
      field: self.$t(`fields.${field}`),
      other: self.$t(`fields.${other}`)
    })
  }
}

validations.strength = ({ self, field }) => {
  return function required (val) {
    const property = self.validationArgs[field].strength
    const strength = self[property]
    return strength < 0.6 || self.$t('validations.strength', {
      field: self.$t(`fields.${field}`)
    })
  }
}

A regra compare serve para comprar o valor de dois campos, o campo other é definido no validationArgs.compare.

A regra strength testa a força de uma senha, no caso, este valor varia de 0 à 1, por hora, iremos definir um valor de 0.6 como aceitável, o validationArgs.strength possui o nome da propriedade computada que realiza o calculo.

Agora, precisamos instalar o pacote zxcvbn, pois iremos utiliza-lo para validar a força da senha:

yarn add zxcvbn

Então, podemos criar a nossa pagina de registro

QPANC.App/src/pages/home/store.js

import { factory } from '@toby.mosque/utils'
import { Dialog } from 'quasar'

class RegisterPageModel {
  constructor ({
    userName = '',
    confirmUserName = '',
    firstName = '',
    lastName = '',
    password = '',
    confirmPassword = ''
  } = {}) {
    this.userName = userName
    this.confirmUserName = confirmUserName
    this.firstName = firstName
    this.lastName = lastName
    this.password = password
    this.confirmPassword = confirmPassword
  }
}

const options = {
  model: RegisterPageModel
}

export default factory.store({
  options,
  actions: {
    async initialize ({ state }, { route, next }) {
    },
    async register ({ state }) {
      await this.$axios.post('/Auth/Register', state)
      this.$router.push('/login')
      Dialog.create({
        color: 'positive',
        message: this.$t('register.success')
      })
    }
  }
})

export { options, RegisterPageModel }

Na store não há nada de novo.

QPANC.App/src/pages/home/index.js

import validations from 'services/validations'
import { factory } from '@toby.mosque/utils'
import store, { options } from './store'
import zxcvbn from 'zxcvbn'

const moduleName = 'page-register'
export default factory.page({
  name: 'RegisterPage',
  options,
  moduleName,
  storeModule: store,
  created () {
    if (process.env.CLIENT) {
      this.$root.$on('unprocessable', this.unprocessable)
    }
  },
  destroy () {
    if (process.env.CLIENT) {
      this.$root.$off('unprocessable', this.unprocessable)
    }
  },
  data () {
    const self = this
    const validation = validations(self, {
      userName: ['required', 'email', 'server'],
      confirmUserName: ['required', 'compare', 'email'],
      firstName: ['required'],
      lastName: ['required'],
      password: ['required', 'strength', 'server'],
      confirmPassword: ['required', 'compare']
    })
    return {
      validation,
      validationArgs: {
        userName: {
          server: true
        },
        confirmUserName: {
          compare: 'userName'
        },
        password: {
          server: true
        },
        confirmPassword: {
          compare: 'password'
        }
      }
    }
  },
  computed: {
    strength () {
      if (!this.password) {
        return 0
      }
      const strength = zxcvbn(this.password).score + 1
      return strength / 5
    },
    strColor () {
      switch (this.strength) {
        case 1: return 'blue'
        case 0.8: return 'green'
        case 0.6: return 'yellow'
        case 0.4: return 'orange'
        case 0.2: return 'red'
        default: return 'grey'
      }
    }
  },
  methods: {
    unprocessable (errors) {
      switch (true) {
        case !!errors.UserName: this.validationArgs.userName.server = errors.UserName[0]; break
        case !!errors.Password: this.validationArgs.password.server = errors.Password[0]; break
      }
      this.$refs.form.validate()
    },
    async register () {
      this.validation.resetServer()
      const isValid = await this.$refs.form.validate()
      if (isValid) {
        this.$store.dispatch(`${moduleName}/register`)
      }
    }
  }
})

No script do componente, você pode observar o data, onde agora temos as regras compare e strength, e no confirmUserName estamos a definir as depedencias para estas validações.

No computed, temos o strength e strColor, que é utilizado para mensurar a força do password.

Lembrando que a regra usada pelo zxcvbn não é a mesma regra que é utilizado no servidor, por tanto, o back pode vir a reclamar da senha, mesmo que o fronto aprove, então o ideal é que use o zxcvbn no backend, ou replique os requerimentos do back no front

QPANC.App/src/pages/home/index.sass

#page-register

QPANC.App/src/pages/home/index.vue

<template>
  <div id="page-register">
    <h5 class="q-my-md">{{$t('register.title')}}</h5>
    <q-separator></q-separator>
    <q-form ref="form" class="row q-col-gutter-sm">
      <div class="col col-12">
        <q-input v-model="userName" :label="$t('fields.userName')" :rules="validation.userName" @blur="validationArgs.userName.server = true"></q-input>
      </div>
      <div class="col col-12">
        <q-input v-model="confirmUserName" :label="$t('fields.confirmUserName')" :rules="validation.confirmUserName"></q-input>
      </div>
      <div class="col col-12">
        <q-input v-model="firstName" :label="$t('fields.firstName')" :rules="validation.firstName"></q-input>
      </div>
      <div class="col col-12">
        <q-input v-model="lastName" :label="$t('fields.lastName')" :rules="validation.lastName"></q-input>
      </div>
      <div class="col col-12">
        <q-input type="password" v-model="password" :label="$t('fields.password')" :rules="validation.password" @blur="validationArgs.password.server = true"></q-input>
        <q-linear-progress size="10px" stripe :value="strength" :color="strColor" ></q-linear-progress>
      </div>
      <div class="col col-12">
        <q-input type="password" v-model="confirmPassword" :label="$t('fields.confirmPassword')" :rules="validation.confirmPassword"></q-input>
      </div>
      <div class="col col-5">
        <q-btn class="full-width" color="secondary" :label="$t('actions.backLogin')" to="/login"></q-btn>
      </div>
      <div class="col col-7">
        <q-btn class="full-width" color="positive" :label="$t('actions.register')" @click="register"></q-btn>
      </div>
    </q-form>
  </div>
</template>

<script src="./index.js"></script>
<style src="./index.sass" lang="sass"></style>

A unica novidade aqui, é a presença do QLinearProgress.

E agora, um vídeo com o processo de registro e login

Discussion (0)