adds option to whitelist image domains
This commit is contained in:
parent
f88960c561
commit
6adec9a8d2
@ -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.
|
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
|
show_retraction_warning
|
||||||
-----------------------
|
-----------------------
|
||||||
|
@ -974,6 +974,7 @@ describe("A Chat Message", function () {
|
|||||||
expect(msg.textContent.trim()).toEqual('hello world');
|
expect(msg.textContent.trim()).toEqual('hello world');
|
||||||
expect(msg.querySelectorAll('img').length).toEqual(2);
|
expect(msg.querySelectorAll('img').length).toEqual(2);
|
||||||
|
|
||||||
|
// @XXX This test isn't really testing anything - needs revisiting
|
||||||
// Non-https images aren't rendered
|
// Non-https images aren't rendered
|
||||||
message = base_url+"/logo/conversejs-filled.svg";
|
message = base_url+"/logo/conversejs-filled.svg";
|
||||||
expect(view.content.querySelectorAll('img').length).toBe(4);
|
expect(view.content.querySelectorAll('img').length).toBe(4);
|
||||||
@ -985,7 +986,31 @@ describe("A Chat Message", function () {
|
|||||||
message = 'http://imgur.com/xxxxxxx';
|
message = 'http://imgur.com/xxxxxxx';
|
||||||
mock.sendMessage(view, message);
|
mock.sendMessage(view, message);
|
||||||
await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-image').length === 5, 1000);
|
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();
|
done();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -120,9 +120,9 @@ function addHyperlinks (text, onImgLoad, onImgClick) {
|
|||||||
text.addTemplateResult(
|
text.addTemplateResult(
|
||||||
url_obj.start,
|
url_obj.start,
|
||||||
url_obj.end,
|
url_obj.end,
|
||||||
show_images && u.isImageURL(url_text) ?
|
show_images && u.isImageURL(url_text) && u.isImageDomainAllowed(url_text)
|
||||||
u.convertToImageTag(url_text, onImgLoad, onImgClick) :
|
? u.convertToImageTag(url_text, onImgLoad, onImgClick)
|
||||||
u.convertUrlToHyperlink(url_text),
|
: u.convertUrlToHyperlink(url_text)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -82,6 +82,18 @@ u.isImageURL = url => {
|
|||||||
? regex.test(url)
|
? regex.test(url)
|
||||||
: checkFileTypes(['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.svg'], 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) {
|
function getFileName (uri) {
|
||||||
try {
|
try {
|
||||||
@ -294,24 +306,9 @@ u.escapeHTML = function (string) {
|
|||||||
.replace(/"/g, """);
|
.replace(/"/g, """);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
u.convertToImageTag = function (url, onLoad, onClick) {
|
u.convertToImageTag = function (url, onLoad, onClick) {
|
||||||
const uri = getURI(url);
|
return tpl_image({url, onClick, onLoad});
|
||||||
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});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
u.convertURIoHyperlink = function (uri, urlAsTyped) {
|
u.convertURIoHyperlink = function (uri, urlAsTyped) {
|
||||||
let normalized_url = uri.normalize()._string;
|
let normalized_url = uri.normalize()._string;
|
||||||
|
Loading…
Reference in New Issue
Block a user