Joi validate 2 schemas conditionally - Invalid schema content - javascript

I'm trying to add conidial schema according of the value of the isCat field in the request body, here is what I have so far:
ror [ERR_ASSERTION]: Invalid schema content` error.What am I missing? Thanks.

Try this
Joi.object({
params: Joi.object({
id: Joi.number().required().integer().min(1),
}),
body: Joi.object({
code: Joi.string().required(),
}).when(Joi.ref("$isValid"), {
is: Joi.equal(true),
then: Joi.object({
body: Joi.object({
...entity,
}),
}),
otherwise: Joi.object({
body: Joi.object({
...put,
}),
}),
}),
});
Verify the reference given by you is right Joi.ref("$isValid").
If you provide right reference, this schema will work as you expect.

Related

Joi validate one of two schemas

I have a simple object with few fields that I would like to validate. I wish to allow or a specific validation schema or that all of the properties have empty values
I created the following two schemas:
const nonEmptyUserInfoValidationSchema = Joi.object({
url: Joi.string().uri().required(),
username: Joi.string().required().min(usernameMinLength),
password: Joi.string().required().min(passwordMinLength),
});
const emptyUserInfoValidationSchema = Joi.object({
url: Joi.string().empty().required(),
username: Joi.string().empty().required(),
password: Joi.string().empty().required(),
});
I wish to create schema that validates if emptyUserInfoValidationSchema or nonEmptyUserInfoValidationSchema is applied but I can't figure out how to do it, any suggestions?
allowed:
{url:"http://some.url", username:"some username", password:"some password"}
{url:"", username:"", password:""}
not allowed:
{url:"http://some.url", username:"", password:""}
Well I finally found what I was looking for joi.alternatives:
export const ansibleInfoValidationSchema = Joi.alternatives(emptyUserInfoValidationSchema , nonEmptyUserInfoValidationSchema );
seems to do the trick
You use the .keys().and() to specify peers. This means that none of the fields specified in the .and() will exist without each other. Hence should be used as so:
const schema = Joi.object({
url: Joi.string().uri(),
username: Joi.string().min(usernameMinLength),
password: Joi.string().min(passwordMinLength)
}).keys().and('url', 'username', 'password');
I hope this helps you can use the when condition in Joi
var schema = Joi.object({
url : Joi.any().when('username',{
is: Joi.empty(),
then: Joi.empty().required(),
otherwise: Joi.string().required()
}),
username: Joi.when('password',{
is: Joi.empty(),
then: Joi.empty(),
otherwise: Joi.string().required().min(usernameMinLength)
})
});
here's a link to when docs Joi When Condtion

Validate only one single field of a bigger Joi schema

I want to use Joi for form field validation and want to stick with one big schema object for validation of the whole form, yet I want to run single entry validation after one form field has been changed - i.e. after the first form field has recieved a value, I do not want to validate the complete form, but only the one field updated. I am envisioning something like
const schema = Joi.object({
username: Joi.string()
.alphanum()
.min(3)
.max(30)
.required(),
password: Joi.string()
.pattern(new RegExp('^[a-zA-Z0-9]{3,30}$'))
.required(),
});
const validationResult = schema.username.validate('Tommy');
Is that possible?
Yes, by extracting the username schema to a separate schema like so:
const username_schema = Joi.string()
.alphanum()
.min(3)
.max(30)
.required();
const schema = Joi.object({
username: username_schema,
password: Joi.string()
.pattern(new RegExp('^[a-zA-Z0-9]{3,30}$'))
.required(),
});
const validationResult = username_schema.validate('Tommy');

Node.JS - #hapi/joi - any.when() - not able to add .validate() at the "then condition"

I'm not able to set the joi-schema that it is working as expected...
This is what I try to do:
'role' is an array and can contain items as string. Any value is allowed.
But when 'internal' is set to 'true', only certain values in 'role' are allowed.
This is the code, which is not working as expected.
let Joi = require("#hapi/joi");
const schema = Joi.object({
internal: Joi.boolean(),
role:
Joi.array()
.items(Joi.string().trim())
.required()
// the when condition is not replacing properly
.when('internal', {
is: true,
then: Joi.array()
.items(Joi.string().valid("Admin"))
.required()
}),
});
console.log(schema.validate({role: ["Any Role"]})) // OK
console.log(schema.validate({internal: false, role: ["Any role allowed"]})) // OK
console.log(schema.validate({internal: true, role: ["WRONG"]})) // FAIL, should have thrown error
... while the replacing array function by itself works fine:
const passingschema = Joi.object({
role: Joi.array()
.items(Joi.string().valid("Admin"))
.required()
})
console.log(passingschema.validate({role: ["Admin"]})) // OK
console.log(passingschema.validate({role: ["WRONG"]})) // OK - throws error as expected
});
Please let me know, how to replace the role validation accordingly, once internal is set to true.
Maybe try is: valid(true).required() in the documentation it says you need required() on the is in order to make this work.
According to this link, this is the solution:
Joi.array().required()
.when('internal', {
is: true,
then: Joi.array().items(Joi.string().valid("Admin")),
otherwise: Joi.array().items(Joi.string())
})

How to import functions from another file in NodeJS?

I'm new in NodeJS, and I'm struggling a little bit on this. I'm using Express and to validate the data, I'm using Celebrate.
I've got a route.js file, where I make a POST request, using a function from another file to do so (it's the create function, from MyController. It works fine! But when I try to do the same thing to my validator, it doesn't work.
So let's take a look at the code.
The route.js file:
const express = require("express");
const MyController = require("./controllers/MyController");
const MyValidator= require("./validators/MyValidator");
const routes = express.Router();
routes.post("/path", MuValidator.validateCreate, MyController.create);
The MyValidator file:
module.exports = {
validateCreate() {
celebrate({
[Segments.HEADERS]: Joi.object({
authorization: Joi.string().required(),
}).unknown(),
[Segments.BODY]: Joi.object().keys({
userId: Joi.string().required(),
title: Joi.string().required(),
description: Joi.string().required(),
value: Joi.number().required(),
dueDate: Joi.string().required(),
}),
});
},
}
IMPORTANT:
I only get this working, if I write the validation code directly on my route, like this:
routes.post(
"/path",
celebrate({
[Segments.HEADERS]: Joi.object({
authorization: Joi.string().required(),
}).unknown(),
[Segments.BODY]: Joi.object().keys({
userId: Joi.string().required(),
title: Joi.string().required(),
description: Joi.string().required(),
value: Joi.number().required(),
dueDate: Joi.string().required(),
}),
}),
MyController.create
);
the problem is that the celebrate function creates and returns a middleware, so the middleware returned by the celebrate function must be passed as second parameter to the post but you're passing a function that execute the celebrate method instead, so validateCreate should be:
module.exports = {
validateCreate: celebrate({...})
}
I think you did something wrong with module exports
try something like this:
module.exports = {
validateCreate: function() {},
otherMethod: function() {},
};

NodeJS joi returns error = null, even though error should occur

I'm running NodeJS with joi, and are trying to validate IBM Watson IoT config object.
This is my schema:
const schema = {
body: {
config: Joi.object().keys({
org: Joi.string().required(),
type: Joi.string().required(),
id: Joi.string().required(),
domain: Joi.string().required(),
'auth-method': Joi.string().required(),
'auth-token': Joi.string().required()
}).required()
}
};
And this is my check:
Joi.validate(req.body, schema, { allowUnknown: true }, (err, value) => {
console.log(err);
});
This returns null as error which indicates no error, but this is even if I haven't POSTed any parameters to my body.
Basically I want to make sure the body of my HTTP POST contains valid JSON object like so:
config = {
"org" : "organization",
"id" : "deviceId",
"domain": "internetofthings.ibmcloud.com",
"type" : "deviceType",
"auth-method" : "token",
"auth-token" : "authToken"
};
You're not passing Joi object to the validate function, you should be passing schema.body.config instead of schema. If body and config is supposed to be part of the validation, you should wrap them with Joi.Object the same way you did for all the keys inside config.

Categories