adonisjs / validator

Schema based validator for AdonisJS
MIT License
115 stars 40 forks source link

Passing options to the rule not working? #162

Closed wakjoko closed 1 year ago

wakjoko commented 1 year ago

Hi

i'm coming from laravel and learning both adonisjs and typescript at the moment

i have a case where i need to validate old password given is the same as previously been set in user's data so i tried with example from Passing options to the rule

so here's my custom rule setup:

_start/validatorrules.ts

import { validator } from '@ioc:Adonis/Core/Validator'
import PasswordValidator from 'password-validator'

validator.rule(
    'oldPasswordMatch',
    async (value, hashed, options) => {
        console.log(value, hashed, options)

        if (!false) {
            options.errorReporter.report(
                options.pointer,
                'oldPasswordMatch',
                'oldPasswordMatch does not match',
                options.arrayExpressionPointer
            )
        }
    },
    () => {
        return {
            async: true,
            compiledOptions: {},
        }
    }
)

contracts/validator.ts

declare module '@ioc:Adonis/Core/Validator' {
    interface Rules {
        hasLowercase(): Rule,
        hasUppercase(): Rule,
        hasDigit(): Rule,
        hasSymbol(): Rule,
        oldPasswordMatch(hashed: string | null): Rule,
    }
}

app/Validators/ChangePasswordValidator.ts

import { schema, rules } from '@ioc:Adonis/Core/Validator'
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import Messages from './Messages'

export default class ChangePasswordValidator extends Messages {
  constructor(protected ctx: HttpContextContract) {
    super()
    console.log('ChangePasswordValidator', this.ctx.auth.user!.password)
  }

  public schema = schema.create({
    old_password: schema.string([
      rules.oldPasswordMatch(this.ctx.auth.user!.password)
    ]),
    password: schema.string([
      rules.required(),
      rules.confirmed(),
      rules.hasLowercase(),
      rules.hasUppercase(),
      rules.hasDigit(),
      rules.hasSymbol(),
      rules.minLength(8)
    ])
  })
}

app/Controllers/Http/PasswordController.ts

import type { HttpContextContract } from "@ioc:Adonis/Core/HttpContext";
import ChangePasswordValidator from 'App/Validators/ChangePasswordValidator';

export default class PasswordController {
  public async update({ request, auth, session, response }: HttpContextContract) {
    const data = await request.validate(ChangePasswordValidator)
    const user = auth.user!

    await user.merge(data).save()
    session.flash('message', 'Your new password has been set!')

    return response.redirect().back()
  }
}

all other custom rules without any options works like charm but only with an option does not work i'm expecting to get the same value at console.log(value, hashed, options) as per shown in console.log('ChangePasswordValidator', this.ctx.auth.user!.password) but it's always empty

another way to approach this is by getting user model in the custom rule file, _start/validatorrules.ts in my case but guess i'm too dumb, can't figure that out by myself

"@adonisjs/validator": "^12.4.1" node v16.19.1 npm 8.19.3

stale[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.