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.