ember-fastboot / ember-cli-fastboot

Server-side rendering for Ember.js apps
http://ember-fastboot.com/
MIT License
852 stars 160 forks source link

Shoebox.put/retrieve fail for invalid CSS selectors #846

Open hoIIer opened 2 years ago

hoIIer commented 2 years ago

When using fastboot shoebox to load initial data for a detail route, if the key value includes invalid css, shoebox.put() will fail due to the underlying querySelect not recognizing the characters.

For example, one way to add shoebox to a model route is to include it in an adapter such as shown here.

When a user navigates to mysite.com/myroute/abc, where the route uses store.findRecord('modelname', param_id), the adapter will check shoebox and/or put the fetched item into it for future retrieval.

The problem arises when a user attempts to navigate to an invalid model id such as mysite.com/myroute/%3Cabc

%3C is invalid css and so document.querySelector() will fail.

Whereas we want the site to gracefully recognize that a record doesn't exist for that id, and render a 404, instead fastboot will crash due to L41 here.

To fix this issue we need to CSS escape the key prior to inserting it into the shoebox store, and likewise unescape it when we pull it out.

Unfortunately node doesn't have a CSS.escape() natively, so we could use a shim based off the mozilla shim, or use the mozilla shim directly. https://developer.mozilla.org/en-US/docs/Web/API/CSS/escape https://github.com/mathiasbynens/CSS.escape/blob/master/css.escape.js https://gist.github.com/burritoIand/440f537e057768b93d038665482b1ae8

The working solution then becomes:

    key = CSSShim.escape(param_id);
    ...
    this.fastboot.shoebox.put(key, result);
    this.fastboot.shoebox.retrieve(CSSShim.escape(key));

If we added this to L41 above then there would be no need for handling it in userland.