url.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import URI from 'urijs';
  2. import log from '@converse/headless/log';
  3. import { api } from '@converse/headless/core';
  4. function checkTLS (uri) {
  5. const uri_protocol = uri.protocol().toLowerCase();
  6. return (
  7. window.location.protocol === 'http:' ||
  8. (window.location.protocol === 'https:' && ['https', 'aesgcm'].includes(uri_protocol))
  9. );
  10. }
  11. export function getURI (url) {
  12. try {
  13. return url instanceof URI ? url : new URI(url);
  14. } catch (error) {
  15. log.debug(error);
  16. return null;
  17. }
  18. }
  19. function checkFileTypes (types, url) {
  20. const uri = getURI(url);
  21. if (uri === null || (window.location.protocol !== 'chrome-extension:' && !checkTLS(uri))) {
  22. return false;
  23. }
  24. const filename = uri.filename().toLowerCase();
  25. return !!types.filter(ext => filename.endsWith(ext)).length;
  26. }
  27. export function isDomainWhitelisted (whitelist, url) {
  28. const uri = getURI(url);
  29. const subdomain = uri.subdomain();
  30. const domain = uri.domain();
  31. const fulldomain = `${subdomain ? `${subdomain}.` : ''}${domain}`;
  32. return whitelist.includes(domain) || whitelist.includes(fulldomain);
  33. }
  34. export function shouldRenderMediaFromURL (url_text, type) {
  35. const may_render = api.settings.get('render_media');
  36. const is_domain_allowed = isDomainAllowed(url_text, `allowed_${type}_domains`);
  37. if (Array.isArray(may_render)) {
  38. return is_domain_allowed && isDomainWhitelisted (may_render, url_text);
  39. } else {
  40. return is_domain_allowed && may_render;
  41. }
  42. }
  43. export function filterQueryParamsFromURL (url) {
  44. const paramsArray = api.settings.get('filter_url_query_params');
  45. if (!paramsArray) return url;
  46. const parsed_uri = getURI(url);
  47. return parsed_uri.removeQuery(paramsArray).toString();
  48. }
  49. export function isDomainAllowed (url, setting) {
  50. const allowed_domains = api.settings.get(setting);
  51. if (!Array.isArray(allowed_domains)) {
  52. return true;
  53. }
  54. try {
  55. return isDomainWhitelisted(allowed_domains, url);
  56. } catch (error) {
  57. log.debug(error);
  58. return false;
  59. }
  60. }
  61. /**
  62. * Accepts a {@link MediaURL} object and then checks whether its domain is
  63. * allowed for rendering in the chat.
  64. * @param { MediaURL } o
  65. * @returns { Bool }
  66. */
  67. export function isMediaURLDomainAllowed (o) {
  68. return o.is_audio && isDomainAllowed(o.url, 'allowed_audio_domains') ||
  69. o.is_video && isDomainAllowed(o.url, 'allowed_video_domains') ||
  70. o.is_image && isDomainAllowed(o.url, 'allowed_image_domains');
  71. }
  72. export function isURLWithImageExtension (url) {
  73. return checkFileTypes(['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.svg'], url);
  74. }
  75. export function isGIFURL (url) {
  76. return checkFileTypes(['.gif'], url);
  77. }
  78. export function isAudioURL (url) {
  79. return checkFileTypes(['.ogg', '.mp3', '.m4a'], url);
  80. }
  81. export function isVideoURL (url) {
  82. return checkFileTypes(['.mp4', '.webm'], url);
  83. }
  84. export function isImageURL (url) {
  85. const regex = api.settings.get('image_urls_regex');
  86. return regex?.test(url) || isURLWithImageExtension(url);
  87. }
  88. export function isEncryptedFileURL (url) {
  89. return url.startsWith('aesgcm://');
  90. }