routed-links.js 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import Ember from 'ember';
  2. export default Ember.Component.extend({
  3. _clicksHandlerName: function() {
  4. return 'click.MisagoDelegatedLinks-' + this.get('elementId');
  5. }.property('elementId'),
  6. cleanHref: function(router, href) {
  7. if (!href) { return; }
  8. // Is link relative?
  9. var isRelative = href.substr(0, 1) === '/' && href.substr(0, 2) !== '//';
  10. // If link contains host, validate to see if its outgoing
  11. if (!isRelative) {
  12. var location = window.location;
  13. // If protocol matches current one, strip it from string
  14. // otherwhise stop handler
  15. if (href.substr(0, 2) !== '//') {
  16. var hrefProtocol = href.substr(0, location.protocol.length + 2);
  17. if (hrefProtocol !== location.protocol + '//') { return; }
  18. href = href.substr(location.protocol.length + 2);
  19. } else {
  20. href = href.substr(2);
  21. }
  22. // Host checks out?
  23. if (href.substr(0, location.host.length) !== location.host) { return; }
  24. href = href.substr(location.host.length);
  25. }
  26. // Is link within Ember app?
  27. var rootUrl = router.get('rootURL');
  28. if (href.substr(0, rootUrl.length) !== rootUrl) { return; }
  29. // Is link to media/static/avatar server?
  30. // NOTE: In ember serve staticUrl equals to /, making clean always fail
  31. var staticUrl = this.get('staticUrl');
  32. if (href.substr(0, staticUrl.length) === staticUrl) { return; }
  33. var mediaUrl = this.get('mediaUrl');
  34. if (href.substr(0, mediaUrl.length) === mediaUrl) { return; }
  35. var avatarsUrl = '/user-avatar/';
  36. if (href.substr(0, avatarsUrl.length) === avatarsUrl) { return; }
  37. return href;
  38. },
  39. delegateLinkClickHandler: function() {
  40. var self = this;
  41. var router = this.container.lookup('router:main');
  42. this.$().on(this.get('_clicksHandlerName'), 'a', function(e) {
  43. var cleanedHref = self.cleanHref(router, e.target.href);
  44. /*
  45. If href was cleaned, prevent default action on link
  46. and tell Ember's router to handle cleaned href instead.
  47. NOTE: there's no way to reliably decide if user didn't maliciously
  48. post an URL to something that should be routed by server instead, like
  49. admin control panel.
  50. If this happens, clicks on those links will fail in Ember's router,
  51. resulting in 404 page for valid urls, confusing your users.
  52. ...not like it's not your moderators job to keep an eye on what your
  53. users are posting on your own site.
  54. */
  55. if (cleanedHref) {
  56. e.preventDefault();
  57. router.handleURL(cleanedHref);
  58. }
  59. });
  60. }.on('didInsertElement'),
  61. removeLinkClickHandler: function() {
  62. this.$().off(this.get('_clicksHandlerName'));
  63. }.on('willDestroyElement')
  64. });