Refactor checkFileTypes

- Don't check the protocol in `checkFileTypes`, it should be doing one
    thing only, and that is check whether the URL ends with a particular
    file extension.
- Raise an error when a URI object can't be created from the passed in URL

Adds new function `isAllowedProtocolForMedia` which checks whether the
URL points to a file on the file system (`file:`), is in a Chrome
extension or uses HTTPs.

Use that in `shouldRenderMediaFromURL` to filter out URLs that shouldn't
be rendered.

Re-add utility methods to the `u` object so that 3rd party plugins can
use them.
This commit is contained in:
JC Brand 2022-03-29 19:31:36 +02:00
parent be561addfa
commit c3933426b9

View File

@ -1,12 +1,24 @@
import URI from 'urijs';
import log from '@converse/headless/log';
import { api } from '@converse/headless/core';
import { api, converse } from '@converse/headless/core';
function checkTLS (uri) {
const uri_protocol = uri.protocol().toLowerCase();
const { u } = converse.env;
/**
* Given a url, check whether the protocol being used is allowed for rendering
* the media in the chat (as opposed to just rendering a URL hyperlink).
* @param { String } url
* @returns { Boolean }
*/
function isAllowedProtocolForMedia(url) {
const uri = getURI(url);
const { protocol } = window.location;
if (['chrome-extension:','file:'].includes(protocol)) {
return true;
}
return (
window.location.protocol === 'http:' ||
(window.location.protocol === 'https:' && ['https', 'aesgcm'].includes(uri_protocol))
protocol === 'http:' ||
(protocol === 'https:' && ['https', 'aesgcm'].includes(uri.protocol().toLowerCase()))
);
}
@ -19,10 +31,19 @@ export function getURI (url) {
}
}
/**
* Given the an array of file extensions, check whether a URL points to a file
* ending in one of them.
* @param { String[] } types - An array of file extensions
* @param { String } url
* @returns { Boolean }
* @example
* checkFileTypes(['.gif'], 'https://conversejs.org/cat.gif?foo=bar');
*/
function checkFileTypes (types, url) {
const uri = getURI(url);
if (uri === null || (!['chrome-extension:','file:'].includes(window.location.protocol) && !checkTLS(uri))) {
return false;
if (uri === null) {
throw new Error(`checkFileTypes: could not parse url ${url}`);
}
const filename = uri.filename().toLowerCase();
return !!types.filter(ext => filename.endsWith(ext)).length;
@ -37,6 +58,9 @@ export function isDomainWhitelisted (whitelist, url) {
}
export function shouldRenderMediaFromURL (url_text, type) {
if (!isAllowedProtocolForMedia(url_text)) {
return false;
}
const may_render = api.settings.get('render_media');
const is_domain_allowed = isDomainAllowed(url_text, `allowed_${type}_domains`);
@ -103,3 +127,15 @@ export function isImageURL (url) {
export function isEncryptedFileURL (url) {
return url.startsWith('aesgcm://');
}
Object.assign(u, {
isAudioURL,
isGIFURL,
isVideoURL,
isImageURL,
isURLWithImageExtension,
checkFileTypes,
getURI,
shouldRenderMediaFromURL,
isAllowedProtocolForMedia,
});