rethinkdb-websocket-server
rethinkdb-websocket-server copied to clipboard
Query validation of array data
What's the best way to validate a query like this? For example, to ensure id > 0
r.table('test').insert([{id: 1}, {id: -1}]) // Query
r.table('test').insert(RP.check(arr => arr.every(e => e.id > 0))) // Whitelist entry
Whitelisting like this fails, I think because arr is a parsed query as opposed to a js array. I'm not sure how to loop through it.
Also, related, but I'm not sure how to validate queries of the form:
r.table('test').getAll('id1', 'id2', 'id3')
For example, comparing the id's in the getAll against a valid list.
For your first query, you're right that its not working because the arr
is still in ReQL AST instead of a vanilla JS array. A workaround for now would be:
const MAKE_ARRAY = 2;
const checkArr = checkFn => term => (
Array.isArray(term)
&& term.length === 2
&& term[0] === MAKE_ARRAY
&& Array.isArray(term[1])
&& checkFn(term[1])
);
// whitelist entry
r.table('test').insert(
checkArr(arr => arr.every(e => e.id > 0))
)
But this should ideally be addressed at the library level. I think it'll probably be safest to make something like RP.checkArr
and RP.refArr
, even though it might feel nicer to just seamlessly convert arrays to vanilla JS in RP.check
and RP.ref
, since it might be hard to do securely without leaving out edge cases.
I don't think there's an easy way to do validate variable number of arguments like getAll
. I'll need to think more about that one.
Great, thanks! This helps a lot for now.
Regarding variable number of arguments, I'm thinking a workaround for now is to pass an array wrapped in r.args
instead of spreading the array into multiple arguments? Not 100% sure where to go from there, but I imagine it becomes a lot more similar to the example you provided of dealing with the AST.
Great idea using r.args
, that should work for getAll
, and then yes you can use the same RP.checkArr
workaround above. You can do:
r.table('test').getAll(
r.args(checkArr(arr => arr.every(e => e.id > 0)))
)
Assuming the rethinkdb backend supports r.args
anywhere, then there should be no need to implement a special case for whitelisting functions with variable number of arguments.