uniform-team / Uniform-Validation-Language

A logic language to simplify and improve online form validation.
Apache License 2.0
1 stars 0 forks source link

Add Checkbox Support #36

Closed dgp1130 closed 7 years ago

dgp1130 commented 8 years ago

Currently, Uniform assumes that all inputs are strings / textboxes. We will need to add support for checkboxes, particularly so we can complete the basic car form example. It should be possible to:

valid: hasCar equals true;
dgp1130 commented 8 years ago

Added support for checkboxes. The car form example is officially complete and works the way it was originally intended!

Unfortunately... When it comes to server side support, checkboxes kind of fall apart. The problem comes down to this, when the user submits a checked box, the browser sends the string "on", and when the user submits an unchecked box, the client sends nothing (as if the input did not exist at all).

To compensate for this, the server assumes that any input with the string "on" must be a checked box, and any input with no value must be an unchecked box. This is very bad, because a textbox with the string "on" will be interpreted correctly on the client (a string of value "on"), but will become a checked box on the server (a boolean of value true). Also an undefined identifier will throw an error on the client side, but will become an unchecked box (a boolean of value false) on the server.

You can even see this in car form. Give make or model the value "on" and submit. The client will accept that value, but the server will interpret it as true and error out (since true matches @filled is a TypeError). There is no easy way to address this, and I can only imagine it will get worse. Radio buttons don't submit any value either if no button is selected. This will make it impossible for the server to distinguish between false checkboxes and unselected radio buttons.

The only "easy" way I can think of to get around this would be to have Uniform encode the data in the special way. Currently, the browser sends the data and Uniform doesn't change the format. We could force the type to be included in the request as well, but that has its own issues. A malicious client could lie and send an incorrect type. That could easily cause the server validation to misbehave and result in false positives. I don't think this would be a safe option, there are too many ways it could be abused.

The "harder" way, would be to modify the language to include type information. I think there will need to be some syntax in Uniform to define a particular type, that way the server will force any data from the client to be that type with no ambiguity. Something along the lines of:

boolean: hasCar; // Expect hasCar to be a boolean
string: make; // Expect make to be a string
string: model; // Expect model to be a string

valid: hasCar and make matches /"."/ and model matches /"."/;

If the request input doesn't match the type specified by the code, then fail instantly and mark the request as invalid. Since the type information is stored in the Uniform code, it can be trusted and any invalid requests can be filtered out and blocked. Any thoughts @sawyernovak?

dgp1130 commented 8 years ago

Whoops, forgot to put this in code review. Mah bad.

dgp1130 commented 8 years ago

Spun off #48 to deal with the typing issue that was brought up here.