Giter Site home page Giter Site logo

validator's Introduction

@adonisjs/validator


gh-workflow-image npm-image license-image

Introduction

This is the repo for the legacy Validator mainly used by AdonisJS v5. We ported it to AdonisJS 6 in order to allow users to easily migrate to AdonisJS 6.

The new validator is now Vine.js and we recommend migrating to it and using it for new projects.

Official Documentation

The documentation for the legacy validator is available on the AdonisJS website

Contributing

One of the primary goals of AdonisJS is to have a vibrant community of users and contributors who believes in the principles of the framework.

We encourage you to read the contribution guide before contributing to the framework.

Code of Conduct

In order to ensure that the AdonisJS community is welcoming to all, please review and abide by the Code of Conduct.

License

AdonisJS Mail is open-sourced software licensed under the MIT license.

validator's People

Contributors

adamcikado avatar assertchris avatar benswinburne avatar dependabot[bot] avatar dolu89 avatar ebaeza avatar greenkeeper[bot] avatar greenkeeperio-bot avatar gusflopes avatar gustavopch avatar julien-r44 avatar liaosankai avatar lookingit avatar m4gie avatar mastermunj avatar maximemrf avatar mcsneaky avatar popovicieduard avatar romainlanz avatar ruby184 avatar shaned24 avatar targos avatar thetutlage avatar vong3432 avatar xstoudi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

validator's Issues

Bug to class name

If create validator using path the class name bug.

Example:
adonis make:validator User/index

Output:

'use strict'

class User/index {
  get rules () {
    return {
      // validation rules
    }
  }
}

module.exports = User/index

add support for validation files

the benefits are
1- better validation messages
2- easily editable and extended
3- support multi-lang apps validation

i made a simple implementation

const fs = require('fs');
const file = Helpers.resourcesPath('locales/en/validation.json')
const messages = JSON.parse(fs.readFileSync(file, 'utf8'));
const validation = yield Validator.validateAll(sanitize, User.rules, messages)
  • validation.json
{
    "above": "The {{field}} should be above {{argument.0}}.",
    "accepted": "The {{field}} should have been accepted",
    "after": "The {{field}} should be after define {{argument.0}}",
    "after_offset_of": "The {{field}} should be after {{argument.0}} from today’s date",
    // ...
}


but not sure how u would incorporate into the core

The class name invalid when generate Validator file using command

Package version

v5.0.9

Node.js and npm version

Node v10.16.0
npm v6.9.0
OS: Ubuntu 18.04 LTS

Description

I installed your package into my Adonisjs project and also tried to generate Validator file by your command. But I still detect this bug. The 'adonis make:validator User/CreateUser' command create the new file in ./Validators/User/CreateUser.js but the 'class name' still invalid -UserCreateUser.

validator for resource not working

my route configuration

    Route
        .resource('products/categories', 'ProductCategoryController')
        .validator(new Map([
            ['products/categories.store', 'StoreProductCategory']
        ]))
        .apiOnly()

the validation no work, any suggestions?

Allow validators on resourceful routes

Structuring The Issue

Route validators are a really cool addition to Adonis, but it doesn't look like they currently work with resourceful routes. It would be cool if we could apply a validator to a Route.resource instance and have the Validator and Sanitizer automatically applied to select routes.

Sample Code

Route.resource('users', 'UsersController')
          .validator('User')

Error Stack

TypeError: Cannot read property 'middleware' of undefined
    at _.castArray.reduce.forEach (/home/watzon/.../node_modules/@adonisjs/framework/src/Route/Resource.js:279:35)
    at Array.forEach (<anonymous>)
    at RouteResource.middleware (/home/watzon/.../node_modules/@adonisjs/framework/src/Route/Resource.js:278:10)
    at RouteResource.validator (/home/watzon/.../node_modules/@adonisjs/validator/providers/ValidatorProvider.js:116:12)
    at Route.group (/home/watzon/.../start/routes.js:21:11)
    at RouteManager.group (/home/watzon/.../node_modules/@adonisjs/framework/src/Route/Manager.js:341:5)
    at Object.<anonymous> (/home/watzon/.../start/routes.js:18:7)
    at Module._compile (module.js:635:30)
    at Object.Module._extensions..js (module.js:646:10)
    at Module.load (module.js:554:32)
    at tryModuleLoad (module.js:497:12)
    at Function.Module._load (module.js:489:3)
    at Module.require (module.js:579:17)
    at require (internal/module.js:11:18)
    at _preLoadFiles.forEach (/home/watzon/.../node_modules/@adonisjs/ignitor/src/Ignitor/index.js:369:9)
    at Array.forEach (<anonymous>)

    at Array.forEach (<anonymous>)

Using Adonis 4.0.0

Validator number rule is not defined

Hi there. I am trying to create rules for a request using validator, however when i add the ‘number’ rule which is available on indicative documentation; I get this error:

[
    {
        "field": "cost",
        "validation": "ENGINE_EXCEPTION",
        "message": "number is not defined as a validation"
    }
]

here is my code:

  const rules = {
  manufacturer: 'required|integer',
  cost: 'required|number',
  items: 'required|array'
}
const validation = await Validator.validate(request.all(), rules)

Using integer works however I want to allow for decimals in the cost property.
Thanks in advance

After sanitizor, object not changed

Set on route validation.

Route
  .post('/registration', 'UserController.startCreate')
  .validator('CreateUser')

Set sanitizor rules.

  get sanitizationRules () {
    return {
      tel: 'format_tel'
    }
  }

After sanitization and success validation i get not mutated object. Why?

Running validations after authorization

It seems a bit pointless to run validation checks if the authorization denies access to the endpoint.

in this file:
validator/src/Middleware/Validator.js :: handler()

Ability to use both syntax styles in same rule

Why this feature is required (specific use-cases will be appreciated)?

I'm attempting to use multiple Validators (required, unique) in congruence with a custom RegEx expression, like so:

const rules = {
      mac_address:[ 'required', 'unique:units,mac_address', rule('regex', new RegExp('^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$'))],
    }

However, in the above rules only the RegEx is actually validated. The others don't work unless I remove the RegEx rule.

Have you tried any other work arounds?

I've poked around a little bit with the above, but was unable to come up with a solution on my own. I've created a question on the Forum in Help>Validator here.
Someone on the Discord suggested creating extending Validator. This worked, but what I was originally attempting still seems favorable.
I spent more time looking around on the Forum for similar questions, but I wasn't able to find anything, though it could have been my search terms.

Are you willing to work on it with little guidance?

I could try, but my confidence level is not high in regards to myself working on this alone.

Sanitizing user input - not working

app/Validators/Test.js

'use strict'

class Test {
  get validateAll() {
    return true
  }

  get rules() {
    return {
      'email': 'email',
      'age': 'number'
    }
  }

  get sanitizationRules() {
    return {
      'email': 'normalize_email',
      'age': 'to_int'
    }
  }

  async fails(errorMessages) {
    return this.ctx.response.send(errorMessages)
  }
}


module.exports = Test

route.js

Route.get('/test', 'TestController.test').validator('Test')

and

Route.post('test', 'TestController.test').validator('Test')

app/Controllers/Http/TestController.js

class TestController {
    test({ response, request }) {

        const data = request.only(['email', 'age'])

        return response.send({
            data: data,
            int: typeof (sanitizeData.age)
        })
    }
}

module.exports = TestController

INPUT

email:bar.sneaky+foo@googlemail.com
age:22

OUTPUT:

[
    {
        "message": "email validation failed on email",
        "field": "email",
        "validation": "email"
    },
    {
        "message": "number validation failed on age",
        "field": "age",
        "validation": "number"
    }
]

Describing validators

Hi,is it possible to describe the validator once (as class or object) and use it in different places: ace commands, controller or as middleware?

Get value of the rule parameter

It would be useful if we can get the value of the parameter of a given rule.
Let say we have something like that :

{
  "_default": "Field {field} is not valid.",
  "min": "Field {field} must contain at least {min} character(s)."
}
get rules () {
  return {
    username: 'required|min:3|max:15|unique:users,username',
    email: 'required|email|max:30|unique:users,email',
    password: 'required|min:6|max:60'
  }
}

async fails (errorMessages) {
    let error = errorMessages[0] // Remove that if validateAll returns true.
    let messageData = {
      field: error.field
    }

    messageData[error.validation] = error.rule // <-- Notice here the new property. It should print of course 3 because "min:3" if there's a min error.

    return this.ctx.response.send({
      field: error.field,
      message: Antl.formatMessage(`validation.${error.validation ? error.validation : '_default'}`, messageData)
    })
  }

What do you think about that?

Validation error on database error

The following code with the mysql driver produces an unexpected behavior when the database is down.

* signup(request, response) {

        const details = request.only(['username', 'email', 'password'])
        const validation = yield Validator.validate(details, User.rules)

        if (validation.fails()) 
          console.log(validation.messages())
}
[ { field: 'username',
    validation: 'unique',
    message: 
     { [Error: connect ECONNREFUSED 127.0.0.1:3306]
       code: 'ECONNREFUSED',
       errno: 'ECONNREFUSED',
       syscall: 'connect',
       address: '127.0.0.1',
       port: 3306,
       fatal: true } } ]

I'm not sure if this is by design, but it feels wrong to me.

Indicative version upgrade dependency

Why this feature is required (specific use-cases will be appreciated)?

I would like to use the new features present in Indicative v7.2.0 but @adonisjs/validator v5.0.6 have an old dependency : "indicative": "^5.0.8"

Have you tried any other work arounds?

No

Are you willing to work on it with little guidance?

It depends of the work...

Validation Not Working

I tried sending nothing in request but validation is not failing

/** Validate If NOT NULL [ title, content, tags ] */
 let title = request.input("title");
 let content = request.input("content");
 let tags = request.input("tags");

    const validation = yield Validator.validate(
      request.all(),
      TextContent.rules,
      "All fields Required"
    );

    if (validation.fails()) {
      response.json(validation.messages());
      return;
    }
    response.json({
      success: true,
      message: "Post Added"
    });

npm: Installation failed

✖ npm: Installation failed

=============================================
Installation failed due to following error
=============================================
Command failed: npm install --save @adonisjs/validator
npm ERR! Unexpected end of input at 1:8289
npm ERR! oad/cross-env-5.0.0.tgz"},"engines":{"node":">=4.0"},"_hasShrinkwrap"
npm ERR!                               ^

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/lynnleung/.npm/_logs/2018-02-12T10_14_43_231Z-debug.log

for more

0 info it worked if it ends with ok
1 verbose cli [ '/usr/local/Cellar/node/8.9.1/bin/node',
1 verbose cli   '/usr/local/bin/npm',
1 verbose cli   'install',
1 verbose cli   '--save',
1 verbose cli   '@adonisjs/validator' ]
2 info using [email protected]
3 info using [email protected]
4 verbose npm-session cd870496c78d4183
5 silly install loadCurrentTree
6 silly install readLocalPackageData
7 http fetch GET 304 https://registry.npm.taobao.org/@adonisjs%2fvalidator 487ms (from cache)
8 silly pacote tag manifest for @adonisjs/validator@latest fetched in 505ms
9 silly install loadIdealTree
10 silly install cloneCurrentTreeToIdealTree
11 silly install loadShrinkwrap
12 silly install loadAllDepsIntoIdealTree
13 silly resolveWithNewModule @adonisjs/[email protected] checking installable status
14 http fetch GET 304 https://registry.npm.taobao.org/@adonisjs%2fgeneric-exceptions 107ms (from cache)
15 silly pacote range manifest for @adonisjs/generic-exceptions@^2.0.0 fetched in 109ms
16 silly resolveWithNewModule @adonisjs/[email protected] checking installable status
17 http fetch GET 304 https://registry.npm.taobao.org/lodash 517ms (from cache)
18 http fetch GET 304 https://registry.npm.taobao.org/indicative 519ms (from cache)
19 silly pacote range manifest for lodash@^4.17.5 fetched in 520ms
20 silly resolveWithNewModule [email protected] checking installable status
21 silly pacote range manifest for indicative@^5.0.5 fetched in 522ms
22 silly resolveWithNewModule [email protected] installable status
23 http fetch GET 304 https://registry.npm.taobao.org/upcast 115ms (from cache)
24 silly pacote range manifest for upcast@^2.1.1 fetched in 117ms
25 silly resolveWithNewModule [email protected] checking installable status
26 http fetch GET 304 https://registry.npm.taobao.org/node-exceptions 387ms (from cache)
27 silly pacote range manifest for node-exceptions@^3.0.0 fetched in 389ms
28 silly resolveWithNewModule [email protected] checking installable status
29 http fetch GET 304 https://registry.npm.taobao.org/cross-env 659ms (from cache)
30 silly fetchPackageMetaData error for cross-env@^5.1.0 Unexpected end of input at 1:8289
30 silly fetchPackageMetaData oad/cross-env-5.0.0.tgz"},"engines":{"node":">=4.0"},"_hasShrinkwrap"
30 silly fetchPackageMetaData     ^
31 verbose stack SyntaxError: Unexpected end of input at 1:8289
31 verbose stack oad/cross-env-5.0.0.tgz"},"engines":{"node":">=4.0"},"_hasShrinkwrap"
31 verbose stack                                       ^
31 verbose stack     at Object.parseJSON (/usr/local/lib/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/node-fetch-npm/node_modules/json-parse-helpfulerror/node_modules/jju/lib/parse.js:745:13)
31 verbose stack     at parse (/usr/local/lib/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/node-fetch-npm/node_modules/json-parse-helpfulerror/index.js:10:13)
31 verbose stack     at consumeBody.call.then.buffer (/usr/local/lib/node_modules/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/node-fetch-npm/src/body.js:96:50)
31 verbose stack     at <anonymous>
31 verbose stack     at process._tickCallback (internal/process/next_tick.js:188:7)
32 verbose cwd /Users/lynnleung/workspace/adonis-demo
33 verbose Darwin 17.4.0
34 verbose argv "/usr/local/Cellar/node/8.9.1/bin/node" "/usr/local/bin/npm" "install" "--save" "@adonisjs/validator"
35 verbose node v8.9.1
36 verbose npm  v5.3.0
37 error Unexpected end of input at 1:8289
37 error oad/cross-env-5.0.0.tgz"},"engines":{"node":">=4.0"},"_hasShrinkwrap"
37 error                               ^
38 verbose exit [ 1, true ]

Validator fails to send custom error message

Goal

Send a custom message to the client when data validation fails

Package version

5.0.6

Node.js and npm version

npm: 6.4.1
node.js: v10.15.3
adonisjs: 4.1

Client code

 async post() {
   const town = new FormData()
   town.set('name', this.townName)
   const config = {
      headers: {
        'accept': 'application/json'
      }
    }
    try {
      await this.$axios.$post('towns', town, config)
    } catch (e) {
      console.log(e.message)
    }
 }

Server code

'use strict'

class StoreTown {
  
  get rules () {
    return {
      name: "required|unique:towns"
    }
  }

  get messages() {
    return {
      'name.required': 'Hello there',
      'name.unique': 'Hello there'
    }
  }

  async fails() {
    return this
      .ctx
      .response
      .status(403)
      .json({
        message: 'Hello there' // Does not work
        // Below does not work either
        // message: errorMessages[0].message
      })
  }
}

module.exports = StoreTown

Expected behavior

I expect to receive "Hello there" message on the client side when data is not valide

Actual behavior

  • On the client side, I get this message: ‘Request failed with status code 403’
  • I also get Request failed with status code 400 if I remove completely fails() method, instead of getting the custom messages I defined above.

BONUS (a sample repo to reproduce the issue)

Link

Unique validation rule should support an ignore row clause using a field/value pair

Unique validation rule must support a field/value pair to ignore a row when doing the validation. It will be helpful when trying to update the field.

Current Signature

const rules = {
    email: 'unique:users,email'
}

Now when trying to update the user with the payload that has the same email address, will cause a unique validation failure, since this email has already been taken.

What we need is a way to ignore the current user by accepting another parameter that will have add the ignore clause to the unique validation.

New Signature

Here id,1 is a way to tell the unique validator, to ignore the row where id=1

const rules = {
    email: 'unique:users,email,id,1'
}

Usage when updating logged in user profile

When trying to update profile of a logged in user, you are likely going to have the logged in user id.

app/Model/User

class User extends Lucid {

  static rules (userId) {
     return {
        email: `unique:users,email,id,${userId}`
     }
  }

}

Now when trying to validate the user input, you can fetch the rules like the following example

app/Http/Controllers/UserController

class UserController {

  * update (request, response) {
       const rules = User.rules(request.currentUser.id)
       yield Validator.validate(request.all(), rules)
   }

}

Note:

I am open for more suggestions on the same.

Got several EPEERINVALID warnings.

I migrated today to adonis-framework 2 and got some EPEERINVALID warnings.

npm WARN EPEERINVALID [email protected] requires a peer of adonis-fold@^2.0.0 but none was installed.
npm WARN EPEERINVALID [email protected] requires a peer of adonis-fold@^2.0.0 but none was installed.
npm WARN EPEERINVALID [email protected] requires a peer of adonis-fold@^2.0.0 but none was installed.
npm WARN EPEERINVALID [email protected] requires a peer of adonis-fold@^2.0.0 but none was installed.

validation.fails() always return true

hi , i have the latest version for now @adonisjs/vlidator v5.0.3, and i copied the same example in the docs ,but always return true the ,and if there is an ability to check all the request inputs and return single json response have the checks for all the inputs , coz now the validator in each request check the first input if have error return without continue the next inputs
thanks

Cannot extend sanitizer

Hello, I'm kind of stuck trying to extend the default sanitizier:

Version of @adonisjs/validator: ^5.0.6
Snippet:

const { ioc } = require('@adonisjs/fold')
const { hooks } = require('@adonisjs/ignitor')

hooks.after.providersRegistered(() => {
  const { sanitizor } = ioc.use('Validator')
  const something = async () => {
    console.log("this should say something on console")
  }

  sanitizor.extend('something', something)
})

Expected:

 SERVER STARTED
> Watching files for changes...
info: serving app on http://127.0.0.1:3333

Got:

TypeError: sanitizor.extend is not a function

at /home/charlie/Projects/Backend/microservices/herm-core/start/hooks.js(hooks.after.providersRegistered):33
28    const { sanitizor } = ioc.use('Validator')
29    const something = async () => {
30      throw new Error('this should fail')
31    }
32
33    sanitizor.extend('something', something)
34  })
35

1 hooks.(anonymous function).get.forEach
  /home/charlie/Projects/Backend/microservices/herm-core/node_modules/@adonisjs/ignitor/src/Ignitor/index.js:137

2 Ignitor._callHooks
  /home/charlie/Projects/Backend/microservices/herm-core/node_modules/@adonisjs/ignitor/src/Ignitor/index.js:137

3 Ignitor._registerProviders
  /home/charlie/Projects/Backend/microservices/herm-core/node_modules/@adonisjs/ignitor/src/Ignitor/index.js:272

4 Ignitor.fire
  /home/charlie/Projects/Backend/microservices/herm-core/node_modules/@adonisjs/ignitor/src/Ignitor/index.js:760

5 Ignitor.fireHttpServer
  /home/charlie/Projects/Backend/microservices/herm-core/node_modules/@adonisjs/ignitor/src/Ignitor/index.js:810

6 anonymous
  /home/charlie/Projects/Backend/microservices/herm-core/server.js:25

Application crashed, make sure to kill all related running process, fix the issue and re-run the app

Thanks in advance

[Feature Request] include request.validated() to get all valid fields from request

Why this feature is required (specific use-cases will be appreciated)?

I use Route validator. And I only want get valid fields. Other fields do not define in Rules will be remove.

UserStore.js

class UserStore {
  get rules() {
    return {
      username: "required|unique:users",
      email: "required|email|unique:users",
      password: "required"
    };
  }
}

UserController.js

async store({ request, response }) {
    $input = request.only(['username','email','password']);
   // In laravel, just need: $input = $request->validated();
   // I needn't repeat again above step
    const user = await User.create($input)
}

I thing this feature will help faster's code and security because all data alway valid. Before use in controller.

Proposition to extend framework "request" instance with validate method

It would be great to extend framework "request" instance in validation provider for same possibility as has laravel 5.5 framework

$validatedData = $request->validate([
        'title' => 'required|unique:posts|max:255',
        'body' => 'required'
    ]);
async request.validate({
    title: 'required|unique:posts|max:255',
    body: 'required'
})

If the validation rules pass, your code will keep executing normally; however, if validation fails, an exception will be thrown and the proper error response will automatically be sent back to the user. In the case of a traditional HTTP request, a redirect response will be generated, while a JSON response will be sent for AJAX requests.

it would make validation more simply than:

const { validate } = use('Validator')

class UserController {

  async store ({ request, session, response }) {
    const rules = {
      email: 'required|email|unique:users,email',
      password: 'required'
    }

    const validation = await validate(request.all(), rules)

    if (validation.fails()) {
      session
        .withErrors(validation.messages())
        .flashExcept(['password'])

      return response.redirect('back')
    }

unique is not defined as a validation

Unique validator not registered.

...
    this.app.singleton('Adonis/Addons/Validator', function (app) {
      const validator = require('../src/Validator')
      /**
       * Wrap database unique rule inside a try/catch block
       * incase someone is not using Lucid
       */
      try {
        const Database = app.use('Adonis/Src/Database')
        const extendedRules = new ExtendedRules(Database)
        validator.extend('unique', extendedRules.unique.bind(extendedRules), '{{field}} has already been taken by someone else')
      } catch (e) {
        console.log(e)
       // Error: Cannot find module 'config/ami.js'
      }
      return validator
    })
...

May be to use bind instead singleton? This should solve the problem.

Allow validations messages to be localized out of the box.

Original message: Copied from adonisjs/discussion#62

I wonder if validator messages will looking for translation (if available) by default. For example, if we have unique, required or any validations error it will looking for available translation first, otherwise use default message.

The translation file would be located in resources/locales/<locale>/validations.json & should contains the following

// resources/locales/<locale>/validations.json
{
  "unique": "The {field} should be unique",
  "required": "The {field} is required",
  "range": "The {field} should between {0} and {1}"
}

I've done this by creating simple helper that dump all validation keys from indicative like this:

Helpers.validationMessages = () => {
  const formats = {}
  const rules = require('indicative/builds/validations')

  for (let rule of Object.keys(rules)) {
    rule = rule.split(/(?=[A-Z])/).join('_').toLowerCase()

    formats[rule] = (field, type, args) => {
      const params = { field, ...args }
      try {
        return Antl.formatMessage(`validations.${type}`, params)
      } catch (err) {
        Logger.debug('Validation translation not found', { err })
      }
    }
  }

  return formats
}

That way I could simply use validate(data, rules, Helpers.validationMessages), so I don't have to translate each form manually.

I thought it would be great if adonis could handle this kind of functionality by default.

P.s. Hope you guys get the idea even tho my english was so poor 😁

Putting custom messages in locales files

I think in mvc model (when we have edge views) validation messages is more related to views (front end ) than backend (controller) + some times we need separate validation message for each language .

So I think ability to set custom messages in locales files will be good (Laravel has this feature too. we can set messages on lang(locales) files & also controller)
Thank you.

Bug to class name

From @RomainLanz on June 8, 2018 21:50

@danielsalles commented on Mon Feb 19 2018

If create validator using path the class name bug.

Example:
adonis make:validator User/index

Output:

'use strict'

class User&#x2F;index {
  get rules () {
    return {
      // validation rules
    }
  }
}

module.exports = User&#x2F;index

@alanaasmaa commented on Sat Mar 24 2018

I have same issue.

Did you get the validator to work in sub folder ?


@thetutlage commented on Sat Mar 24 2018

It shouldn’t stop u from using it, simply put the class name manually.

Also I’ll fix the cli to produce the right class name


@alanaasmaa commented on Sat Mar 24 2018

@thetutlage Damn u reply fast.

I tried to fix class name manually but it did not work. I get 204 No Content from my api.


@thetutlage commented on Sat Mar 24 2018

204 is not an error, also response code is not a way to find if something works or not.

Make sure your controller does return something or calls response.send

Copied from original issue: adonisjs/adonis-cli#111

Number validation fail without sanitize

I have a field with a float (money) value. I tried to apply number validation, but it fails because the value retrieved is a string. Works fine using to_int sanitizer, but in this case, I need a to_number or to_float sanitizer.

Email Validation for rule 'email' fails

I am facing an issue in email validation. While trying to validate emails, I always get this error
[ { message: 'e.hasOwnProperty is not a function', field: 'email', validation: 'ENGINE_EXCEPTION' } ]

I am unable to reproduce the cause and also checked the NPM package, but could not get insights.

Bug on sanitize request

Hello!

Im with a strange behavior when I sanitize user input.
I have a custom sanitizer that transforms metadatas arrays into dynamic jsons.

Custom sanitizor:

  sanitizor.jsonInput = value => {
    const metadata = {};

    value.forEach(element => {
      const [k, v] = element;
      metadata[k] = v;
    });

    return metadata;
  };

My validator:

'use strict';

class StorePlan {
  get validateAll() {
    return true;
  }

  get sanitizationRules() {
    return {
      accept_boleto: 'to_boolean',
      accept_credit_card: 'to_boolean',
      metadata: 'json_input'
    };
  }

  get rules() {
    return {
      name: 'required',
      gateway: 'required',
      amount: 'required|number',
      trial_period_days: 'required|number',
      interval: 'required|in:day,week,month,year',
      interval_count: 'required|number',
      metadata: 'array'
    };
  }
}

My controller:

  async store({ response, request, params, session }) {
    const application = await Application.findOrFail(params.applications_id);
    const planParams = await this.planParams(request);
    const plan = await Plan.create(planParams);
    await plan.application().associate(application);

    session.flash({ alert: 'Plan created successfully' });
    response.route('Admin/Application/PlanController.edit', {
      applications_id: params.applications_id,
      id: plan.id
    });
  }

  async planParams(request) {
    return request.only([
      'name',
      'description',
      'gateway',
      'amount',
      'trial_period_days',
      'interval',
      'interval_count',
      'metadata',
      'accept_boleto',
      'accept_credit_card'
    ]);
  }

When I submit the form, the sanitize works, but it does not replace the metadata content. Instead, it merges the old content with the new content. Like this:

app_1       | {
app_1       |   name: 'Test',
app_1       |   description: 'Test description',
app_1       |   gateway: 'paypal',
app_1       |   amount: '50',
app_1       |   trial_period_days: '15',
app_1       |   interval: 'week',
app_1       |   interval_count: '1',
app_1       |   metadata: [
app_1       |     [ 'foo', 'bar' ],
app_1       |     [ 'bar', 'foo' ],
app_1       |     [ 'acme', 'inc' ],
app_1       |     foo: 'bar',
app_1       |     bar: 'foo',
app_1       |     acme: 'inc'
app_1       |   ],
app_1       |   accept_boleto: true,
app_1       |   accept_credit_card: true
app_1       | }

But if I use the validator/sanitizor in a specific field in my controller, all works fine:

  async store({ response, request, params, session }) {
    const { sanitizor } = use('Validator');
    const application = await Application.findOrFail(params.applications_id);
    const planParams = await this.planParams(request);

    if (planParams.metadata) {
      planParams.metadata = sanitizor.jsonInput(planParams.metadata);
    }

    const plan = await Plan.create(planParams);
    await plan.application().associate(application);

    session.flash({ alert: 'Plan created successfully' });
    response.route('Admin/Application/PlanController.edit', {
      applications_id: params.applications_id,
      id: plan.id
    });
  }

Output:

app_1       | {
app_1       |   name: 'Test',
app_1       |   description: 'Test description',
app_1       |   gateway: 'paypal',
app_1       |   amount: '50',
app_1       |   trial_period_days: '15',
app_1       |   interval: 'week',
app_1       |   interval_count: '1',
app_1       |   metadata: { foo: 'bar', bar: 'foo', acme: 'inc' },
app_1       |   accept_boleto: true,
app_1       |   accept_credit_card: true
app_1       | }

Package version: 4.1.0;
Node version: v12.4.0;
NPM version: 6.9.0

required doesnt work

  • view
<div class="container">
    <div class="row">
        {{ form.open({url: '/form', method: 'POST'}) }}
            
            {% if old('errors') %}
                <div class="alert alert-danger">
                    {% for error in old('errors') %}
                        <li> {{ error.message }} </li>
                    {% endfor %}
                </div>
            {% endif %}
            
            {{ csrfField }}
            
            <div class="col-xs-6">
                {{ form.label('email', 'Email') }}
                {{ form.email('email[]', old('email'), {placeholder:'email', class: 'form-control'}) }}
            </div>
            
            <div class="col-xs-6">
                {{ form.label('password', 'Password') }}
                {{ form.password('password[]', old('password'), {class:'form-control',placeholder: 'password'}) }}
            </div>
            
            <div class="col-xs-12">
                <hr>
            </div>
            
            <div class="col-xs-4">
                {{ form.submit('Create Users', null, {class: 'btn btn-success'}) }}
            </div>
        {{ form.close() }}
    </div>
</div>
  • controller
* store(request, response) {

    let data = request.all();
    const rules = {
        email: 'required',
        password: 'required'
    }

    const validation = yield Validator.validateAll(data, rules);
    response.json(validation);

    if (validation.fails()) {
        yield request.withAll().andWith({ errors: validation.messages() }).flash()
        response.redirect('back')
    }
    
    response.send(data);
}
  • result
{
  "errors": [
    
  ]
}

Sanitise causing problems when run on partial data

Let's say I have a schema with 3 fields:

static get sanitisationRules () {
    return {
      headline: 'escape',
      description: 'escape',
      instructions: 'escape'
  }
}

If I want to only sanitise 2 fields (because they're the only one the user has posted), I pass them like this:

Validator.sanitize({
  description: 'Some description',
  instructions: 'Some instructions'
}, Model.sanitisationRules)

it returns:

{
  headline: undefined
  description: 'Some description',
  instructions: 'Some instructions'
}

When combined with Lucid's fill method it overwrites attributes as undefined which causes me problems when calling toJSON on it later (for passing to a view etc). Luckily it doesn't overwrite it as undefined on save.

Is there a way to make sanitisation rules only return a value when the field is present?
If not, is there a way to make Lucid fill ignore fields that are undefined?

If I can't do that either, what is the best approach to sanitising then updating partial model data? The easiest I can think of is merging the sanitised data with the user-input data so that the undefined fields aren't there at all, then passing it to lucid fill.

Use a validator from a provider

Hi, i have a set of base validators in a provider and i want to use them as a route validator.

I add the singleton in the provider like this:

 this.app.singleton('Nuviio/Validators/UserOwnedListValidator', () => {
      return require('./Validators/UserOwnedListValidator')
    })

And i try to call it in a controller like this.

Route.get('/', 'Api/CampaignController.list')
    .middleware([
      'logRequest',
      'auth:jwt',
      'userIsActive',
      'processQueryParams'
    ]).validator(['Nuviio/Validators/UserOwnedListValidator'])

It always gives me a module_not_found error. Please help.

Rules format & Errors methods

@thetutlage
I find the validator package with rules format and the methods are similar to Laravel validator
https://github.com/skaterdav85/validatorjs
How about if this provider has rules as object and the methods like this:

// rules
var nested = {
  name: 'required',
  bio: {
    age: 'min:18',
    education: {
      primary: 'string',
      secondary: 'string'
    }
  }
};
// OR
var flattened = {
  'name': 'required',
  'bio.age': 'min:18'
  'bio.education.primary': 'string',
  'bio.education.secondary': 'string'
};

//methods:
var validation = new Validator(input, rules);
validation.errors.first('email'); // returns first error message for email attribute
validator.errors.get('email'); // returns an array of error messages for the email attribute

Sorry if you don't like this

Integration with Adonis Antl

I'm looking for a way to internationalize my validations. I've kinda solved the problem by generating messages using rules like in the code below:

const rules = {
  'name': 'required'
}

const messages = Utilities.antlValidationMessages(rules)

const validation = yield Validator.validate(data, rules, messages)

It works but I'm wondering if there is a more elegant solution.

SQL Error using unique rule

It appears that the unique rule is not selecting any tables and causing an SQL error. I've tried providing it as an extra argument like unique:users with no results.

Here is the error:

            "field": "email",
            "validation": "unique",
            "message": {
                "code": "ER_PARSE_ERROR",
                "errno": 1064,
                "sqlMessage": "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where `email` = '[email protected]'' at line 1",
                "sqlState": "42000",
                "index": 0,
                "sql": "select * where `email` = '[email protected]'"
            }

I'm using adonis v4 as well.

Unique Validation Rule Silent Failure

I've been having some difficulty getting the unique:[table],[column],[id],[$id] validation rule to work.

Service Providers are listed and DB table migrations have been run.

Its executed in a UserContoller.store against an empty postgres table where phone_number is set as a unique index. Validation fails but returns no messages for the unique rule, removing the rule allows the insert but naturally throws a DB error on subsequent inserts with the same column value.

I'm using it as follow

class User extends Lucid {

	static get table () {
		return 'st_users';
	}

	...

	static rules ( id ) {
		return {
			'firstname': [ 'required', 'string', 'max:255' ],
			'lastname': [ 'required', 'string', 'max:255' ],
			'organization': [ 'string', 'min:3', 'max:255' ],
			'phone_number': [ 'required', 'regex:^(\\+27|0)[0-9]{9}$', `unique:st_users,phone_number,id,${id}` ]
		};
	}

	...

}

logging the output of

adonis-validation-provider/providers/ValidatorProvider.js

https://github.com/adonisjs/adonis-validation-provider/blob/develop/providers/ValidatorProvider.js#L25

at line 25

} catch (e) {console.error(e)}

Returns this

Error: Cannot find module 'config/app.js'

on startup.

I'm unsure if this is a factor, perhaps the missing module means the DB service cannot load the correct parameters?

Santize query params from middleware dosen't work

I'm trying to sanitize query params using the validator middleware, and this is no posible because in _sanitizeData only validate the post data. This is what you have:

  _sanitizeData (request, validatorInstance) {
    /**
     * Skip sanitization when there are no rules defined
     */
    if (!validatorInstance.sanitizationRules || !_.size(validatorInstance.sanitizationRules)) {
      return true
    }

    const data = request.post() <---------------- Only pass the post data
    const sanitizedData = this.Validator.sanitize(data, validatorInstance.sanitizationRules)

    /**
     * Here we mutate the actual request body, this is required since there is
     * no point keep the actual data when we really want to sanitize it.
     */
    request.body = _.merge({}, data, sanitizedData)
  

I make a PR #47 but you have note reviewed yet

if the validation message is empty, the view should ignore it

currently if the validation message is empty, the view should not render it

static get rules() {
        return {
            email: 'required|email|unique:users,email',
            password: 'required|min:6'
        }
    }
{
  "errors": [
    {
      "field": "email",
      "validation": "email",
      "message": "email validation failed on email"
    },
    {
      "field": "email",
      "validation": "unique",
      "message": {
        
      }
    },
    {
      "field": "password",
      "validation": "min",
      "message": "min validation failed on password"
    }
  ]
}

and we get

email validation failed on email
[object Object]
min validation failed on password

PostgreSQL: unique validation rules does not work

I have unique index set on email column within users table. I had my project running under MySQL and everything was working fine. When I have switched to PostgreSQL 12 unique validation stopped working and app crashes during INSERT command.
500 error screenshot: https://imgur.com/Bq10he4

Package version

5.0.6

Node.js and npm version

Node 10.16.0
Npm 6.11.1

Sample Code (to reproduce the issue)

    let validationRules = {
      name: 'required|string',
      email: 'required|email|unique:users',
      password: 'required|string|min:6',
      terms: 'required|string|equals:yes',
      gdpr: 'required|string|equals:yes'
    }

    const validation = await validate(request.all(), validationRules)
    
    # THIS NEVER HAPPENS WHEN UNIQUE RULE DOES NOT WORK
    if (validation.fails()) {
      return response.badRequest(validation._errorMessages)
    }

Validating user instance in hook

I wanted to move my validation calls into the hooks because this allows me to not worry about calling the validation in the routes or controllers.

Inside my User model I register the hook.

class User extends Model {
  static boot() {
    super.boot();
    this.addHook('beforeSave', 'UserHook.validate');
  }
  static get hidden() {
    return ['password'];
  }
}

and in my User hook I add the validation

UserHook.validate = async (user) => {
const rules = {
    password: 'required|min:8|max:256',
    username: 'required|min:2|max:18',
    mail: 'required|email'
}
 const validation = await validateAll(user, rules);

Afterwards I check if validation.fails() and throw an error which is then handled by the controller that executes queries with lucid. With the code above it can't validate any field and fails with following message:

[
  {
    "field": "password",
    "message": "required validation failed on password",
    "validation": "required"
  },
  {
    "field": "username",
    "message": "required validation failed on username",
    "validation": "required"
  },
  {
    "field": "mail",
    "message": "required validation failed on mail",
    "validation": "required"
  }
]

If I call toJSON() on the user instance only the password validation is missing because the field is hidden.

 const validation = await validateAll(user.toJSON(), rules);
[
  {
    "field": "password",
    "message": "required validation failed on password",
    "validation": "required"
  }
]

If I store the user instance in another object while explicitly calling the properties of the instance e.g user.password, everything works as expected and no field is missing.

UserHook.validate = async (user) => {
const rules = {
    password: 'required|min:8|max:256',
    username: 'required|min:2|max:18',
    mail: 'required|email'
}

const adonisUser = {
  username: user.username,
  password: user.password,
  mail: user.mail
};
const validation = await validateAll(adonisUser, rules);

Is there a more elegant way to validate the user instance?

Allow to define snake_case rules name in Validator.extend()

Why this feature is "required"?

We are using rules in strings like this: required_with:otherField, and when we want to extend the validator with custom rules, we are obliged to define them in camelCase.

That can be a good feature to be able to define them in snake_case too, in order to be more consistent with Indicative :)

Use case: when searching for a custom rule in your IDE, it's super effective to find their definition and usage with the same case/search.

As I can see in this package, it can be done with a snake_case to camelCase converter right here (then add one test and you'll be good ✨):
https://github.com/adonisjs/adonis-validation-provider/blob/2466338ee147c4402a7a2822e8cfaad12676c2f7/src/Validator/index.js#L26

(PS: I was ready to make a PR but I'm pretty sure you will integrate it better than me 😊)

Can't match multiple depth arrays with wildcard

I have the following rule:

{
  "props.exit_urls.*.url": "required"
}

But when I post the following data:

props[exit_urls][0][url] = ''

It isn't matching the rule.

I tried running the regexp arrayExpressionRegex parser rule in src/Parser/index.js and it appears to only match everything after props..

How to extend validator?

Hi
I know this is somehow mentioned in the documentations but it's not documented well !
I've read all docs of current version of Adonis ( 4.1 ) and ( 4.0 ) and also ( 3.2 ). I couldn't find out how to extend it.
I want to add exists to my validator.
There are a bunch of code in the documentation which is not clear WHERE should I paste them and HOW to autoload them or whatever.
Can somebody please make it more clear or any example

Unable to validate properly

My Code:

// Controller
class UserController {
  async store ({ request }) {
    return { success: true }
  }
}

// Route
Route
  .post('/registration', 'UserController.store')
  .validator('UserRegistration')

// Validator
class UserRegistration {
  get rules () {
    return {
      email: 'required|email'
    }
  }

  get sanitizationRules () {
    // sanitize data before validation
    return {
      email: 'normalize_email'
    }
  }

  get formatter () {
    return 'jsonapi'
  }
}

Insomnia:

> POST /registration HTTP/1.1
> Host: localhost:3333
> User-Agent: insomnia/5.14.3
> Accept: application/json
> Content-Type: application/x-www-form-urlencoded
> Content-Length: 29
| email=sample.user%40gmail.com

< HTTP/1.1 400 Bad Request
< Content-Type: application/json; charset=utf-8
< Content-Length: 2
< Date: Fri, 16 Feb 2018 23:46:36 GMT
< Connection: keep-alive

Issue:
If I remove

  get formatter () {
    return 'jsonapi'
  }

I will receive 200. If I include the above, I receive 400.

error: `make:validator` is not a registered command

after installation
img 2018-03-05 20 58 02

AND the set
img 2018-03-05 20 57 50

when you try to run

adonis make:validator User

sees an error

error: `make:validator` is not a registered command

after installing the validator, at startup adonis serve --dev start issuing an error, executed
yarn add @ adonisjs/ignitoreverything worked, including the command adonis make:validator ...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.