mirror of
https://github.com/discourse/discourse.git
synced 2024-11-27 14:53:37 +08:00
f0fc38418c
This commit adds a new property "discourseReferrerPolicy" to the set of supported configuration properties for the comment embed script. If provided the value will be used to set the "referrerPolicy" attribute on the iframe created to display the comments. This in turn will allow embedding pages to define a more lenient referer policy on the embed iframe for pages whose default policy is so strict it keeps the comment embed from working. Example: * Setup: * Discourse hosted at discourse.example.com * Comments embedded at example.com * Referrer-Policy at example.com set to 'same-origin' * Without this commit: * Loading the comments fails due to the referer being empty * With this commit and no adjusted configuration: * Loading the comments fails due to the referer being empty (= same behaviour as without the commit) * With this commit and DiscourseEmbed.discourseReferrerPolicy = 'no-referrer-when-downgrade' as additional configuration: * Loading the comments succeeds Note that this change is of special interest for embedding pages wanting to restrict data flows under the terms of the GDPR since it allows selectively whitelisting comment embeds while preventing referer leaking by default.
97 lines
2.4 KiB
JavaScript
97 lines
2.4 KiB
JavaScript
(function() {
|
|
|
|
var DE = window.DiscourseEmbed || {};
|
|
var comments = document.getElementById('discourse-comments');
|
|
var iframe = document.createElement('iframe');
|
|
|
|
['discourseUrl', 'discourseEmbedUrl', 'discourseUserName', 'discourseReferrerPolicy'].forEach(function(i) {
|
|
if (window[i]) { DE[i] = DE[i] || window[i]; }
|
|
});
|
|
|
|
var queryParams = {};
|
|
|
|
if (DE.discourseEmbedUrl) {
|
|
if (DE.discourseEmbedUrl.indexOf('/') === 0) {
|
|
console.error("discourseEmbedUrl must be a full URL, not a relative path");
|
|
}
|
|
|
|
queryParams.embed_url = encodeURIComponent(DE.discourseEmbedUrl);
|
|
}
|
|
|
|
if (DE.discourseUserName) {
|
|
queryParams.discourse_username = DE.discourseUserName;
|
|
}
|
|
|
|
if (DE.topicId) {
|
|
queryParams.topic_id = DE.topicId;
|
|
}
|
|
|
|
var src = DE.discourseUrl + 'embed/comments';
|
|
var keys = Object.keys(queryParams);
|
|
if (keys.length > 0) {
|
|
src += "?";
|
|
|
|
for (var i=0; i<keys.length; i++) {
|
|
if (i > 0) { src += "&"; }
|
|
|
|
var k = keys[i];
|
|
src += k + "=" + queryParams[k];
|
|
}
|
|
}
|
|
|
|
iframe.src = src;
|
|
iframe.id = 'discourse-embed-frame';
|
|
iframe.width = "100%";
|
|
iframe.frameBorder = "0";
|
|
iframe.scrolling = "no";
|
|
if (DE.discourseReferrerPolicy) {
|
|
// See https://www.w3.org/TR/html5/semantics-embedded-content.html#the-iframe-element
|
|
iframe.referrerPolicy = DE.discourseReferrerPolicy;
|
|
}
|
|
comments.appendChild(iframe);
|
|
|
|
// Thanks http://amendsoft-javascript.blogspot.ca/2010/04/find-x-and-y-coordinate-of-html-control.html
|
|
function findPosY(obj)
|
|
{
|
|
var top = 0;
|
|
if(obj.offsetParent)
|
|
{
|
|
while(1)
|
|
{
|
|
top += obj.offsetTop;
|
|
if(!obj.offsetParent)
|
|
break;
|
|
obj = obj.offsetParent;
|
|
}
|
|
}
|
|
else if(obj.y)
|
|
{
|
|
top += obj.y;
|
|
}
|
|
return top;
|
|
}
|
|
|
|
function normalizeUrl(url) {
|
|
return url.toLowerCase().replace(/^https?(\:\/\/)?/, '');
|
|
}
|
|
|
|
function postMessageReceived(e) {
|
|
if (!e) { return; }
|
|
if (normalizeUrl(DE.discourseUrl).indexOf(normalizeUrl(e.origin)) === -1) { return; }
|
|
|
|
if (e.data) {
|
|
if (e.data.type === 'discourse-resize' && e.data.height) {
|
|
iframe.height = e.data.height + "px";
|
|
}
|
|
|
|
if (e.data.type === 'discourse-scroll' && e.data.top) {
|
|
// find iframe offset
|
|
var destY = findPosY(iframe) + e.data.top;
|
|
window.scrollTo(0, destY);
|
|
}
|
|
}
|
|
}
|
|
window.addEventListener('message', postMessageReceived, false);
|
|
|
|
})();
|