1

Is there a way to whitelist a property value in expressjs? IE I would like to limit a properties values to either a Boolean true/false or the string 'true'/'false'.

Because truthy sucks in JS I cannot just do this

  var foo = Boolean(req.param('foo'));

Since the string 'false' evaluates to true.

Looking to simplify this, however also wondering if there is something built in to expressjs or multer/busboy that I am missin:

var fooParam = req.param('foo');
var foo;
if (fooParam === 'true' || fooParam === 'false') {
  foo = fooParam === 'true;
} else if (fooParam === true || fooParam === false) {
  foo = fooParam;
}
lostintranslation
  • 23,756
  • 50
  • 159
  • 262
  • Out of curiosity, when can it be boolean instead of string `true`/`false`? JSON request bodies? – Ry- Jun 11 '19 at 22:31
  • And to clarify, the three results are: `'true'` or `true` produces `foo = true`, `'false'` or `false` produces `foo = false`, and any other strings or types produce `foo = undefined`? – Ry- Jun 11 '19 at 22:32
  • How about using `typeof fooParam === 'boolean'` in the second `if`? – Krzysztof Dziembała Jun 11 '19 at 22:33
  • @Ry- yes trying to simply a route that can use multipart/form-data and application/json. JSON would of course be a boolean, but multipart values are strings so would come in as 'true'/'false'. – lostintranslation Jun 11 '19 at 22:39
  • 2
    There’s really no super-clean solution to this, just variations on the same thing you already have. – Ry- Jun 11 '19 at 22:42

3 Answers3

0

I do like this notation:

[true, false, 'true', 'false'].includes(req.param('foo'))

It offers great extensibility.

let result: boolean | undefined = undefined;
if ([false, 'false'].includes(req.param('foo'))) {
  result = false;
} else if ([true, 'true'].includes(req.param('foo'))) {
  result = true;
}
Akxe
  • 9,694
  • 3
  • 36
  • 71
0

I'd suggest to tackle it in the opposite direction - stringify the provided value and check the resulting string:

var fooParam = req.param('foo');
// map the string value of each boolean to the corresponding boolean value
var boolMap = new Map([['true', true], ['false', false]]); 
// stringify the provided param (true\'true' => 'true', false\'false' => 'false') 
// and get the corresponding value from the mapping. 
// in case of value that is not true\'true'\false\'false' was provided, undefined will be assigned to foo.
var foo = boolMap.get(String(fooParam));
Reuven Chacha
  • 879
  • 8
  • 20
  • Using an object with a prototype has the issue that `fooParam === 'hasOwnProperty'`, `'toString'`, etc. will give unexpected results. (Sometimes this is even a vulnerability.) A `Map` might be better. – Ry- Jun 12 '19 at 00:48
  • @Ry- I agree. Thanks for the comment, edited the code. – Reuven Chacha Jun 12 '19 at 11:02
-1

Try this:

let maChaine = true;
let monBooleen = JSON.parse(maChaine); 
console.log(monBooleen); //monBoolen vaut true

maChaine = 'true';
monBooleen = JSON.parse(maChaine); 
console.log(monBooleen); //monBoolen vaut true

maChaine = false;
monBooleen = JSON.parse(maChaine); 
console.log(monBooleen); //monBoolen vaut false

maChaine = 'false';
monBooleen = JSON.parse(maChaine); 
console.log(monBooleen); //monBoolen vaut false

so, your code will be:

var fooParam = req.param('foo');
let foo = [true, false, 'true', 'false'].includes(fooParam)?JSON.parse(fooParam):undefined
Ghoul Ahmed
  • 4,446
  • 1
  • 14
  • 23
  • There‘s a lot more valid JSON than just `'true'` and `'false'` though. `'1'`, `'null'`, `'{}'`, `[]`, `'"foo"'` will all give unexpected results. – Ry- Jun 12 '19 at 00:50