I'm using express-validator 5.3.1. I defined password check like this :
check('password')
.not().isEmpty().withMessage('Password can\'t be null')
.isString()
.isLength({ min: 8 }),
check('retypePassword')
.not().isEmpty().withMessage('Password can\'t be null')
.isString().withMessage('Password must be a string')
.custom((value, { req }) => {
if(value.trim() !== req.body.password.trim()) {
throw new Error ('Password confirmation does not match password');
}
}),
For testing, I send same password and retypePassword ('password') and got error :
[
{
"location": "body",
"param": "retypePassword",
"value": "password",
"msg": "Invalid value"
}
]
I defined message with all error of retypePassword, so what's going on ?
When you implement a custom validation you have to return true if the validation succeed, otherwise you will get the "Invalid value" error message. So you just add a return true; statement like this
.custom((value, { req }) => {
if(value.trim() !== req.body.password.trim()) {
throw new Error ('Password confirmation does not match password');
}
return true;
})
Related
After I submit the verification code sent to the user's email after a email update, when I try to verify with verifyAttribute, it throws the following error: "User is not authenticated"
getUser returns a CognitoUser.
onSubmitEmailConfirmation = async (values) => {
const { code, newEmail, password } = this.state;
const { first_name, last_name, email } = this.props.data;
getSession()
.then(({ user, email }) => {
authenticate(email, password).then(() => {
getUser(email).verifyAttribute("email", code, {
onSuccess: () => {
this.props.updateUserData({
email: newEmail,
first_name: first_name,
last_name: last_name
});
this.updateNotificationMessages(
"Email verified with success!",
newEmail
);
this.openNotificationWithIcon("success");
},
onFailure: (err) => {
this.updateNotificationMessages(
"There was a error confirming your email",
err.message
);
this.openNotificationWithIcon("error");
}
});
});
})
.catch((err) => {
this.updateNotificationMessages(
"There was a error confirming your email",
err.message
);
this.openNotificationWithIcon("error");
});
};
I would like to use the checkSchema method instead of what I am currently doing with all the checks on the post route in an array. The problem I have is I can't find good documentation on the syntax used in the object for each key. The doc page for schema validation (https://express-validator.github.io/docs/schema-validation.html) gives one example but no links to all the syntax that defines all the attributes you can use (isInt, toInt, isUppercase, rtrim, etc.) I have searched high and low for the docs that tell you everything you can use there but no luck. Can someone point me in the right place?
express-validator is a set of express.js middlewares that wraps validator.js validator and sanitizer functions.
you can find all the rules available in the link above.
here is a good example how it's used with checkSchema:
import { checkSchema, validationResult } from 'express-validator'
const schema = {
id: {
isFloat: true,
// Sanitizers can go here as well
toFloat: true,
errorMessage: "must be a valid number"
},
first_name: {
exists: {
errorMessage: "first_name is required"
},
isLength: {
errorMessage: "first_name has invalid length",
options: {
min: 1
}
}
},
middle_name: {
optional: {
options: { nullable: true, checkFalsy: true }
}
},
last_name: {
exists: {
errorMessage: "last_name is required"
},
isLength: {
errorMessage: "last_name has invalid length",
options: {
min: 1
}
}
},
date_of_birth: {
isISO8601: {
errorMessage: `date of birth is not a valid iso date`
},
isBefore: {
date: "01-01-2000",
errorMessage: `should be less than 01-01-2000`
},
isAfter: {
date: "01-01-1970",
errorMessage: `should be greater than 01-01-1970`
}
},
email: {
exists: {
errorMessage: "email is required"
},
isEmail: {
errorMessage: "email is invalid"
}
},
current_country_of_residence: {
exists: {
errorMessage: "current_country_of_residence is required",
options: {
checkNull: true,
checkFalsy: true
}
}
},
current_city_of_residence: {
exists: {
bail: true,
errorMessage: "current_city_of_residence is required"
},
isMongoId: {
errorMessage: "current_city_of_residence is has invalid id for"
}
},
email: {
isEmail: { errorMessage: 'email is not a valid email' },
isLength: { errorMessage: 'email has invalid length', options: { min: 1 } }
},
skills: {
isArray: {
errorMessage: `invalid value for skills`,
options: {
min: 3,
max: 5
}
},
isIn: {
options: ["java", "C++", "javascript"],
errorMessage: `allowed values for skills are: ${["java", "C++", "javascript"]}`
},
custom: {
options: (values) => {
const unique_values = new Set(values)
if (unique_values.size !== values.length) {
return Promise.reject()
}
return Promise.resolve()
},
errorMessage: `you can't add duplicated`
},
customSanitizer: {
options: async (value, { req }) => {
return value
}
}
}
}
const validate = () => {
return [
checkSchema(schema),
(req, res, next) => {
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.mapped() })
}
next()
}
]
}
export default validate()
I'm using loopback3.x. Why upsertWithWhere function always updates the same instance? Only one instance is there for all the time when updateWithWhere function executes.
app.models.oneTimePassword.upsertWithWhere({
where: {
userId: user.id
}
}, {
userId: user.id,
otp: otp,
updatedAt: updatedAt,
type: 'email'
}, (err, res) => {
if (!err) {
callback(null, {
status: "OK",
message: "email sent"
});
} else {
callback(err);
}
});
app.models.oneTimePassword.upsertWithWhere(
{
userId: user.id
},
{
userId: user.id,
otp: otp,
updatedAt: updatedAt,
type: 'email'
},
(err, res) => {
if (!err) {
callback(null, {
status: "OK",
message: "email sent"
});
} else {
callback(err);
});
Try this, The first argument of upsertWithWhere should be where therefore, you don't need to add where: {} check out this official documentation
I'm trying to validate the following json that looks like this:
{
"errors": false,
}
using this on postman:
var Ajv = require('ajv'),
ajv = new Ajv({logger: console, coerceTypes: false}),
schema = {
"errors": {
"type": "number"
}
};
pm.test('Schema is valid', function() {
var error = pm.response.json()['errors'];
console.log("this is error: " +error);
pm.expect(ajv.validate(schema, {errors: error})).to.be.true;
});
pm.test('Schema is valid different way', function() {
var error = pm.response.json()['errors'];
console.log("this is error: " +error);
var validate = ajv.compile(schema);
pm.expect(validate(pm.response.json())).to.be.true;
});
but it's always passing, even though my errors object is a boolean and not a number. What am I doing wrong?
note: the logs look like this
this is error: false
You can check json schema using avj in Postman as follows:
var Ajv = require('ajv'),
ajv = new Ajv({logger: console}),
schema = {
"properties": {
"errors": {
"type": "boolean"
}
}
};
pm.test('Schema is valid', function() {
var error = pm.response.json()['errors'];
pm.expect(ajv.validate(schema, {errors: error})).to.be.true;
});
Data:
{
"errors": false
}
Result: Pass
Data:
{
"errors": true
}
Result: Pass
Data:
{
"errors": 123
}
Result: Fail
An alternate way
pm.test('Schema is valid', function() {
pm.expect(typeof(pm.response.json().errors) === "boolean").to.be.true;
});
I'm trying to use the before Remote hook in loopback to check an user token before the call of my remote method, but the thing is that I can only return a javascript Error, like these.
"error": {
"statusCode": 401,
"name": "Error",
"message": ""
}
This is the code that i'm using in the before remote.
Model.beforeRemote('method', function (context, unused, next) {
let token = Model.app.models.Token;
let id = context.args.Id;
let date = moment();
Rx.Observable.fromPromise(token.find({
where: {
and: [
{ id: id, },
{ expiration: { gt: date } }
]
}
})).subscribe((token => {
if (token.length > 0) {
next();
} else {
let err = new Error();
err.status = 401;
delete err.stack;
return next()
}
}))
});
And I need a "custom" response that isn't an error, something like these.
{
"success": false,
"data": {
"service": "self",
"operation": "rest",
"code": "unauthorized"
},
"message": "Invalid token"
}
I tried with the after Remote hook and I can change the response to get something like that, but I want to get a quicker response in the case that the token is invalid.
Is there any way to achieve this with the before hook? or I had to use after hook?
Thanks
You may want to pass the error to the next function:
return next(err)