Commit 6adec9a8 authored by Ariel Fuggini's avatar Ariel Fuggini Committed by JC Brand

adds option to whitelist image domains

parent f88960c5
......@@ -1692,6 +1692,9 @@ show_images_inline
If set to ``false``, images won't be rendered in chats, instead only their links will be shown.
It also accepts an array strings of whitelisted domain names to only render images that belong to those domains.
E.g. ``['imgur.com', 'imgbb.com']``
show_retraction_warning
-----------------------
......
......@@ -974,6 +974,7 @@ describe("A Chat Message", function () {
expect(msg.textContent.trim()).toEqual('hello world');
expect(msg.querySelectorAll('img').length).toEqual(2);
// @XXX This test isn't really testing anything - needs revisiting
// Non-https images aren't rendered
message = base_url+"/logo/conversejs-filled.svg";
expect(view.content.querySelectorAll('img').length).toBe(4);
......@@ -985,7 +986,31 @@ describe("A Chat Message", function () {
message = 'http://imgur.com/xxxxxxx';
mock.sendMessage(view, message);
await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-image').length === 5, 1000);
expect(view.content.querySelectorAll('img').length).toBe(5);
expect(view.content.querySelectorAll('.chat-content .chat-image').length).toBe(5);
done();
}));
it("will render images from approved URLs only",
mock.initConverse(
['rosterGroupsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
await mock.waitForRoster(_converse, 'current');
const base_url = 'https://conversejs.org';
let message = 'http://wrongdomain.com/xxxxxxx.png';
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
await mock.openChatBoxFor(_converse, contact_jid);
_converse.api.settings.set('show_images_inline', ['conversejs.org']);
const view = _converse.api.chatviews.get(contact_jid);
spyOn(view.model, 'sendMessage').and.callThrough();
mock.sendMessage(view, message);
message = base_url+"/logo/conversejs-filled.svg";
mock.sendMessage(view, message);
await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg').length === 2, 1000);
await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-image').length === 1, 1000)
expect(view.content.querySelectorAll('.chat-content .chat-image').length).toBe(1);
done();
}));
......
......@@ -120,9 +120,9 @@ function addHyperlinks (text, onImgLoad, onImgClick) {
text.addTemplateResult(
url_obj.start,
url_obj.end,
show_images && u.isImageURL(url_text) ?
u.convertToImageTag(url_text, onImgLoad, onImgClick) :
u.convertUrlToHyperlink(url_text),
show_images && u.isImageURL(url_text) && u.isImageDomainAllowed(url_text)
? u.convertToImageTag(url_text, onImgLoad, onImgClick)
: u.convertUrlToHyperlink(url_text)
);
});
}
......
......@@ -82,6 +82,18 @@ u.isImageURL = url => {
? regex.test(url)
: checkFileTypes(['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.svg'], url);
}
u.isImageDomainAllowed = url => {
try {
const show_images_inline = api.settings.get('show_images_inline');
const is_domains_array = Array.isArray(show_images_inline);
if (!is_domains_array) return true;
const image_domain = getURI(url).domain();
return show_images_inline.includes(image_domain);
} catch (error) {
log.debug(error);
return true;
}
}
function getFileName (uri) {
try {
......@@ -294,24 +306,9 @@ u.escapeHTML = function (string) {
.replace(/"/g, """);
};
u.convertToImageTag = function (url, onLoad, onClick) {
const uri = getURI(url);
const img_url_without_ext = ['imgur.com', 'pbs.twimg.com'].includes(uri.hostname());
if (u.isImageURL(url) || img_url_without_ext) {
if (img_url_without_ext) {
const format = (uri.hostname() === 'pbs.twimg.com') ? uri.search(true).format : 'png';
return tpl_image({
onClick,
onLoad,
'url': uri.removeSearch(/.*/).toString() + `.${format}`
});
} else {
return tpl_image({url, onClick, onLoad});
}
}
}
return tpl_image({url, onClick, onLoad});
};
u.convertURIoHyperlink = function (uri, urlAsTyped) {
let normalized_url = uri.normalize()._string;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment