DavyJonesLocker / client_side_validations

Client Side Validations made easy for Ruby on Rails
MIT License
2.69k stars 403 forks source link

Devise's email validations (uniqueness and regexp) is not working with client_side_validations #710

Closed salmagomaa closed 7 years ago

salmagomaa commented 7 years ago
  1. Version of ClientSideValidations: 9.3.3
  2. Version of Rails: 5.1.1
  3. Code snippet from your model of the validations:
    
    class User < ApplicationRecord
    include DeviseAsync

devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable end


4. The form code from your template

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), turboboost: true, validate: true, html: {id: "register-form-id"}) do |f| %>

<%= f.email_field :email, class: "form-control", validate: true %>

<% end %>



5. Result:
On blurring the email's input field, an error only shown if it is empty but if it already existed or if it has invalid format, no error is shown.

I need the client_side_validations to be shown for all cases of the email errors, any help please??
tagliala commented 7 years ago

Hi,

uniqueness

Uniqueness validator was removed in version 7.0. It was bugged and not secure. It exposed your app to data disclosure. Also, it was using a blocking ajax request.

Hope it helps

salmagomaa commented 7 years ago

Thank you @tagliala! But I wonder if you help me to use the remote validation instead (as stated here), as I found that the ClientSideValidations::Middleware has been removed too, so do you have any other suggestion?

tagliala commented 7 years ago

You're welcome @salmagomaa

But I wonder if you help me to use the remote validation instead (as stated here), as I found that the ClientSideValidations::Middleware has been removed too, so do you have any other suggestion?

Quoting from: https://github.com/DavyJonesLocker/client_side_validations/issues/692#issuecomment-275408571

In this version, I've completely dropped references to the remote validators, but you should still be able to implement one. Feel free to start a wiki or to open issues if you need extra configuration to do that.

At the moment I can't update that wiki.

My suggestion is to try by yourself, but since you cannot rely on the middleware, you should add a custom controller and action in your Rails Application.

Something like:

# /config/routes

Rails.application.routes.draw do

  # ...

  namespace :validators do
    get :zipcode, to: 'validators#zipcode'
  end

  # ...
end
# /app/controllers/validators/validators_controller.rb

module Validators
  class ValidatorsController < ApplicationController
    def zipcode
      if Zipcode.where(id: params[:id]).exists?
        head :ok
      else
        head :not_found
      end
    end
  end
end
# /app/models/model.rb

class ZipcodeValidator < ActiveModel::EachValidator
  def validate_each(record, attr_name, value)
    unless Zipcode.where(id: value).exists?
      record.errors.add(attr_name, 'is not unique', options.merge(value: value))
    end
  end
end

class Model
  # ...

  validates :zipcode, zipcode: true

  # ...
end
//application.js

window.ClientSideValidations.validators.remote['zipcode'] = function(element, options) {
  if ($.ajax({
    url: '/validators/zipcode',
    data: { id: element.val() },
    // async *must* be false
    async: false
  }).status == 200) { console.log(options); return options.message; }
}

Please note that the above endpoint should be protected by rack attack, works in a different way if the resource is persisted and could allow information disclosure. I would not recommend this solution for an uniqueness validator

I've tested this locally, if you are able to make it work, please update the wiki with the new instructions

Hope it helps

tagliala commented 7 years ago

I've released an updated version of CSV, but it should not fix all devise related issues.

You may still need to specify validate: true near email fields (e.g.: new session)

tagliala commented 7 years ago

Hi, I'm going to close this one.

For people experiencing this issue:

Devise's uniqueness email validation doesn't work

It doesn't work because the uniqueness middleware was removed from the gem in version 7.0 because of security issues (brute force data disclosure). You are still free to implement your own remote validator. I do not advise to downgrade to CSV 6.0

Devise's regexp email validation doesn't work

It works. Please note that in some forms (login, password recovery) you still need to pass validate: true to the email field.

Hope it helps