I'm building a JOI extension to allow me to blacklist certain people from sending certain API values, if they are missing certain roles from their JWT scope.
So far I've go this:
const Joi = require('joi')
const { string, number, ref, required, only, lazy } = Joi.extend(joi => ({
name: 'string',
base: Joi.string(),
language: {
permits: 'you are not allowed to edit {{key}}'
},
pre (value, state, options) {
this.permissions = options.context.auth.credentials.scope
},
rules: [{
name: 'whitelist',
params: {
permits: Joi.array()
},
validate(params, value, state, options) {
const permitted = params.permits.find(value => this.permissions.includes(value))
return permitted ? value : this.createError('string.permits', {}, state, options)
}
}]
}))
Which works perfectly.
However, Note the name and base are set to 'string'. I want this to work for numbers, arrays, objects, you name it.
I've tried this:
name: 'any',
base: Joi.any()
but it doesn't seem to work:
/home/ant/Projects/roles-example/routes/validation.routes.js:55
reference: string().whitelist(['all-loans']),
^
TypeError: string(...).whitelist is not a function
I would assume that any would allow me to append the function to any other type within JOI. But it seems that I can't.
Does anyone have any pointers for me, before I have to start adding this to all of the JOI base types?
The way I solved this problem is by declaring the any
rules separate and adding them all to each Joi type.
const Joi = require('joi')
const anyRules = j => [
{
name: 'whitelist',
params: {
permits: j.array()
},
validate(params, value, state, options) {
const permitted = params.permits.find(value => this.permissions.includes(value))
return permitted ? value : this.createError('string.permits', {}, state, options)
}
}
];
module.exports = Joi
.extend(j => ({
name: 'any',
base: j.any(),
rules: anyRules(j),
}))
.extend(j => ({
name: 'array',
base: j.array(),
rules: anyRules(j).concat([
// ...
]),
}))
.extend(j => ({
name: 'boolean',
base: j.boolean(),
rules: anyRules(j).concat([
// ...
]),
}))
.extend(j => ({
name: 'binary',
base: j.binary(),
rules: anyRules(j).concat([
// ...
]),
}))
.extend(j => ({
name: 'date',
base: j.date(),
rules: anyRules(j).concat([
// ...
]),
}))
.extend(j => ({
name: 'func',
base: j.func(),
rules: anyRules(j).concat([
// ...
]),
}))
.extend(j => ({
name: 'number',
base: j.number(),
rules: anyRules(j).concat([
// ...
]),
}))
.extend(j => ({
name: 'object',
base: j.object(),
rules: anyRules(j).concat([
// ...
]),
}))
.extend(j => ({
name: 'string',
base: j.string(),
rules: anyRules(j).concat([
// ...
]),
}))
.extend(j => ({
name: 'alternatives',
base: j.alternatives(),
rules: anyRules(j).concat([
// ...
]),
}))
;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With