diff options
author | diosmosis <diosmosis@users.noreply.github.com> | 2018-10-03 08:59:54 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-03 08:59:54 +0300 |
commit | 67eaa2c0381933d5e38180a2159044893447acca (patch) | |
tree | 6810978ef7295aeeaeb2256b95712111cea07c96 /plugins/Overlay/client | |
parent | ae872e501015ec5ed5a538c23f6e090ce3089c66 (diff) |
Use postMessage instead of directly making API calls in the overlay iframe. (#13446)
* Use postMessage instead of directly making API calls in the overlay iframe.
* Make sure it will work when Matomo is on a subfolder.
* Increase overlay security with domain and method whitelists.
* Try to fix UI test.
* Fix tests + UI test blacklist check.
* broadcast.getValuesFromUrl does not decode URL params.
Diffstat (limited to 'plugins/Overlay/client')
-rw-r--r-- | plugins/Overlay/client/client.js | 70 |
1 files changed, 58 insertions, 12 deletions
diff --git a/plugins/Overlay/client/client.js b/plugins/Overlay/client/client.js index 9ae78cf3b1..0bd74c371e 100644 --- a/plugins/Overlay/client/client.js +++ b/plugins/Overlay/client/client.js @@ -1,11 +1,16 @@ var Piwik_Overlay_Client = (function () { + var DOMAIN_PARSE_REGEX = /^http(s)?:\/\/(www\.)?([^\/]*)/i; + /** jQuery */ var $; /** Url of the Piwik root */ var piwikRoot; + /** protocol and domain of Piwik root */ + var piwikOrigin; + /** Piwik idsite */ var idSite; @@ -15,12 +20,18 @@ var Piwik_Overlay_Client = (function () { /** Reference to the status bar DOM element */ var statusBar; + /** Counter for request IDs for postMessage based API requests. */ + var lastRequestId = 0; + + /** Map of callbacks for postMessage based API requests. */ + var requestCallbacks = {}; + /** Load the client CSS */ function loadCss() { var css = c('link').attr({ rel: 'stylesheet', type: 'text/css', - href: piwikRoot + 'plugins/Overlay/client/client.css' + href: piwikRoot + '/plugins/Overlay/client/client.css' }); $('head').append(css); } @@ -51,7 +62,7 @@ var Piwik_Overlay_Client = (function () { // check whether the session has been opened in a new tab (instead of an iframe) if (window != window.top) { var iframe = c('iframe', false, { - src: piwikRoot + 'index.php?module=Overlay&action=notifyParentIframe#' + window.location.href + src: piwikRoot + '/index.php?module=Overlay&action=notifyParentIframe#' + window.location.href }).css({width: 0, height: 0, border: 0}); $('body').append(iframe); @@ -81,11 +92,48 @@ var Piwik_Overlay_Client = (function () { return el; } + function nextRequestId() { + var nextId = lastRequestId + 1; + lastRequestId = nextId; + return nextId; + } + + function handlePostMessages() { + window.addEventListener("message", function (event) { + if (event.origin !== piwikOrigin) { + return; + } + + var strData = event.data.split(':', 3); + if (strData[0] !== 'overlay.response') { + return; + } + + var requestId = strData[1]; + if (!requestCallbacks[requestId]) { + return; + } + + var callback = requestCallbacks[requestId]; + delete requestCallbacks[requestId]; + + var data = JSON.parse(decodeURIComponent(strData[2])); + if (typeof data.result !== 'undefined' + && data.result === 'error' + ) { + alert('Error: ' + data.message); + } else { + callback(data); + } + }, false); + } + return { /** Initialize in-site analytics */ initialize: function (pPiwikRoot, pIdSite, pPeriod, pDate, pSegment) { piwikRoot = pPiwikRoot; + piwikOrigin = piwikRoot.match(DOMAIN_PARSE_REGEX)[0]; idSite = pIdSite; period = pPeriod; date = pDate; @@ -95,6 +143,7 @@ var Piwik_Overlay_Client = (function () { var loading = this.loadingNotification; loadJQuery(function () { + handlePostMessages(); notifyPiwikOfLocation(); loadCss(); @@ -138,13 +187,13 @@ var Piwik_Overlay_Client = (function () { }; script.onload = onLoad; - script.src = piwikRoot + relativePath + '?v=1'; + script.src = piwikRoot + '/' + relativePath + '?v=1'; head.appendChild(script); }, /** Piwik Overlay API Request */ api: function (method, callback, additionalParams) { - var url = piwikRoot + 'index.php?module=API&method=Overlay.' + method + var url = piwikRoot + '/index.php?module=API&method=Overlay.' + method + '&idSite=' + idSite + '&period=' + period + '&date=' + date + '&format=JSON&filter_limit=-1'; if (segment) { @@ -155,14 +204,11 @@ var Piwik_Overlay_Client = (function () { url += '&' + additionalParams; } - $.getJSON(url + "&jsoncallback=?", function (data) { - if (typeof data.result != 'undefined' && data.result == 'error') { - alert('Error: ' + data.message); - } - else { - callback(data); - } - }); + var requestId = nextRequestId(); + requestCallbacks[requestId] = callback; + + var matomoFrame = window.parent; + matomoFrame.postMessage('overlay.call:' + requestId + ':' + encodeURIComponent(url), piwikOrigin); }, /** |