I have a password reset form where the validation for new password is such that it should match a regex and should not match the userId of the user. The userId check has to be case insensitive.
I tried lowercase method but then the regex validation fails as the value is transformed to lower case before the validation starts.
newPassword: yup
.string()
.notOneOf(
[yup.ref("oldPassword")],
"New password must be different than current password."
)
.matches(REGEX_PASSWORD, "Password does not meet requirements.")
.lowercase()
.notOneOf(
[userId.toLowerCase()],
"New password must not be same as userId"
)
Is there any method which can be used to transform the value only for userId check so that I can perform case insensitive check without worrying about regex fails.
When using Yup if all normal features fail you you can use the .test
feature, documented here - https://github.com/jquense/yup#mixedtestname-string-message-string--function-test-function-schema
mixed.test(name: string, message: string | function, test: function): Schema
Adds a test function to the validation chain. Tests are run after any object is cast. Many types have some tests built in, but you can create custom ones easily. In order to allow asynchronous custom validations all (or no) tests are run asynchronously. A consequence of this is that test execution order cannot be guaranteed.
As you note from that quoted text is that test (including those build in by Yup such as the ones you normally use) occur after object is cast, hence your issue. However by making your own test you can cast the value inside and do whatever logic you wish. In your instance it may look something like this:
newPassword: yup
.string()
.notOneOf(
[yup.ref("oldPassword")],
"New password must be different than current password."
)
.matches(REGEX_PASSWORD, "Password does not meet requirements.")
.test(
'uidCheck',
'New password must not be the same as userId',
(item) => item !== undefined ? item.toLowerCase() !== userId.toLowerCase() : true
)