Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsgiehl <stefan@matomo.org>2022-07-29 10:47:39 +0300
committersgiehl <stefan@matomo.org>2022-07-29 11:27:35 +0300
commitd19b1da6f30ca4be57eeffaa74b0e39044d3a0cf (patch)
tree6799c27d0484c8f3a81672330adf321004b8240c
parent04c1149d81bd5e48671f212f9a1cbd12fa10ef85 (diff)
parentc7294b3c6cf693abfcdf2096bf910ac9e36fcb6f (diff)
Merge branch 'next_release' into 4.x-devmergetest
-rw-r--r--js/piwik.js5
-rw-r--r--js/piwik.min.js10
-rw-r--r--matomo.js10
-rw-r--r--piwik.js10
-rw-r--r--plugins/Login/tests/Integration/PasswordResetterTest.php7
-rw-r--r--plugins/UsersManager/API.php19
-rw-r--r--plugins/UsersManager/Repository/UserRepository.php11
-rw-r--r--plugins/UsersManager/tests/Integration/APITest.php807
-rw-r--r--plugins/UsersManager/tests/Integration/UserInviteTest.php2
-rw-r--r--plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_all_rows_in_search.png4
-rw-r--r--plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_edit.png4
-rw-r--r--plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_user_created.png4
-rw-r--r--tests/UI/expected-screenshots/UIIntegrationTest_api_listing.png4
13 files changed, 480 insertions, 417 deletions
diff --git a/js/piwik.js b/js/piwik.js
index 274d4ea4ac..deb7e71d59 100644
--- a/js/piwik.js
+++ b/js/piwik.js
@@ -2452,6 +2452,11 @@ if (typeof window.Matomo !== 'object') {
configBrowserFeatureDetection = true;
+ // exclude paypal.com as referrer
+ if (/^https?:\/\/([a-z0-9\.\-]+\.)?paypal\.com(\/|$)/.test(configReferrerUrl)) {
+ configReferrerUrl = '';
+ }
+
// Document title
try {
configTitle = documentAlias.title;
diff --git a/js/piwik.min.js b/js/piwik.min.js
index 940be1433a..24fce26258 100644
--- a/js/piwik.min.js
+++ b/js/piwik.min.js
@@ -30,11 +30,11 @@ at=ai.findFirstNodeHavingAttribute(au,this.CONTENT_PIECE_ATTR);if(!at){at=ai.fin
}if(0===au.search("^[a-zA-Z]{2,11}:")){return au}if(au.search(/^\//)!==-1){return this.getLocation().origin+au}var at="(.*/)";var av=this.getLocation().origin+this.getLocation().pathname.match(new RegExp(at))[0];return av+au},isUrlToCurrentDomain:function(au){var av=this.toAbsoluteUrl(au);if(!av){return false}var at=this.getLocation().origin;if(at===av){return true}if(0===String(av).indexOf(at)){if(":"===String(av).substr(at.length,1)){return false}return true}return false},setHrefAttribute:function(au,at){if(!au||!at){return}ai.setAnyAttribute(au,"href",at)},shouldIgnoreInteraction:function(at){if(ai.hasNodeAttribute(at,this.CONTENT_IGNOREINTERACTION_ATTR)){return true}if(ai.hasNodeCssClass(at,this.CONTENT_IGNOREINTERACTION_CLASS)){return true}if(ai.hasNodeCssClass(at,this.LEGACY_CONTENT_IGNOREINTERACTION_CLASS)){return true}return false}};function aa(au,ax){if(ax){return ax}au=w.toAbsoluteUrl(au);if(A(au,"?")){var aw=au.indexOf("?");au=au.slice(0,aw)}if(U(au,"matomo.php")){au=f(au,"matomo.php".length)
}else{if(U(au,"piwik.php")){au=f(au,"piwik.php".length)}else{if(U(au,".php")){var at=au.lastIndexOf("/");var av=1;au=au.slice(0,at+av)}}}if(U(au,"/js/")){au=f(au,"js/".length)}return au}function R(az){var aB="Matomo_Overlay";var au=new RegExp("index\\.php\\?module=Overlay&action=startOverlaySession&idSite=([0-9]+)&period=([^&]+)&date=([^&]+)(&segment=[^&]*)?");var av=au.exec(J.referrer);if(av){var ax=av[1];if(ax!==String(az)){return false}var ay=av[2],at=av[3],aw=av[4];if(!aw){aw=""}else{if(aw.indexOf("&segment=")===0){aw=aw.substr("&segment=".length)}}W.name=aB+"###"+ay+"###"+at+"###"+aw}var aA=W.name.split("###");return aA.length===4&&aA[0]===aB}function ad(au,az,av){var ay=W.name.split("###"),ax=ay[1],at=ay[2],aw=ay[3],aA=aa(au,az);o(aA+"plugins/Overlay/client/client.js?v=1",function(){Matomo_Overlay_Client.initialize(aA,av,ax,at,aw)})}function v(){var av;try{av=W.frameElement}catch(au){return true}if(M(av)){return(av&&String(av.nodeName).toLowerCase()==="iframe")?true:false}try{return W.self!==W.top
}catch(at){return true}}function T(co,ci){var bR=this,bk="mtm_consent",cT="mtm_cookie_consent",c2="mtm_consent_removed",cd=ae(J.domain,W.location.href,N()),da=O(cd[0]),bW=p(cd[1]),bw=p(cd[2]),c8=false,cs="GET",dt=cs,aM="application/x-www-form-urlencoded; charset=UTF-8",cL=aM,aI=co||"",bQ="",dh="",cy="",cf=ci||"",bH="",bX="",bb,bq="",dp=["7z","aac","apk","arc","arj","asf","asx","avi","azw3","bin","csv","deb","dmg","doc","docx","epub","exe","flv","gif","gz","gzip","hqx","ibooks","jar","jpg","jpeg","js","mobi","mp2","mp3","mp4","mpg","mpeg","mov","movie","msi","msp","odb","odf","odg","ods","odt","ogg","ogv","pdf","phps","png","ppt","pptx","qt","qtm","ra","ram","rar","rpm","rtf","sea","sit","tar","tbz","tbz2","bz","bz2","tgz","torrent","txt","wav","wma","wmv","wpd","xls","xlsx","xml","z","zip"],aC=[da],bI=[],cM=[".paypal.com"],ct=[],bU=[],bf=[],bS=500,dd=true,cZ,bc,b0,bY,at,cC=["pk_campaign","mtm_campaign","piwik_campaign","matomo_campaign","utm_campaign","utm_source","utm_medium"],bP=["pk_kwd","mtm_kwd","piwik_kwd","matomo_kwd","utm_term"],br="_pk_",az="pk_vid",a6=180,df,by,b1=false,aN="Lax",bt=false,c6,bl,bE,c0=33955200000,cz=1800000,dn=15768000000,a9=true,bN=false,bo=false,bZ=false,aV=false,cl,b5={},cx={},bv={},bC=200,cH={},di={},dq={},aZ={},cj=[],bu=false,ck=[],cp=false,cR=false,au=false,dr=false,c3=false,aS=false,bj=v(),cN=null,dg=null,aW,bK,cg=aq,bx,aQ,bJ=false,cE=0,bD=["id","ses","cvar","ref"],cQ=false,bL=null,c1=[],cG=[],aB=X++,aA=false,de=true;
-try{bq=J.title}catch(cO){bq=""}function aH(dE){if(bt&&dE!==c2){return 0}var dC=new RegExp("(^|;)[ ]*"+dE+"=([^;]*)"),dD=dC.exec(J.cookie);return dD?V(dD[2]):0}bL=!aH(c2);function dx(dG,dH,dK,dJ,dE,dF,dI){if(bt&&dG!==c2){return}var dD;if(dK){dD=new Date();dD.setTime(dD.getTime()+dK)}if(!dI){dI="Lax"}J.cookie=dG+"="+t(dH)+(dK?";expires="+dD.toGMTString():"")+";path="+(dJ||"/")+(dE?";domain="+dE:"")+(dF?";secure":"")+";SameSite="+dI;if((!dK||dK>=0)&&aH(dG)!==String(dH)){var dC="There was an error setting cookie `"+dG+"`. Please check domain and path.";ao(dC)}}function cb(dC){var dE,dD;dC=j(dC,az);dC=j(dC,"ignore_referrer");dC=j(dC,"ignore_referer");for(dD=0;dD<ct.length;dD++){dC=j(dC,ct[dD])}if(bY){dE=new RegExp("#.*");return dC.replace(dE,"")}return dC}function b4(dE,dC){var dF=s(dC),dD;if(dF){return dC}if(dC.slice(0,1)==="/"){return s(dE)+"://"+d(dE)+dC}dE=cb(dE);dD=dE.indexOf("?");if(dD>=0){dE=dE.slice(0,dD)}dD=dE.lastIndexOf("/");if(dD!==dE.length-1){dE=dE.slice(0,dD+1)}return dE+dC}function cX(dE,dC){var dD;
-dE=String(dE).toLowerCase();dC=String(dC).toLowerCase();if(dE===dC){return true}if(dC.slice(0,1)==="."){if(dE===dC.slice(1)){return true}dD=dE.length-dC.length;if((dD>0)&&(dE.slice(dD)===dC)){return true}}return false}function cw(dC){var dD=document.createElement("a");if(dC.indexOf("//")!==0&&dC.indexOf("http")!==0){if(dC.indexOf("*")===0){dC=dC.substr(1)}if(dC.indexOf(".")===0){dC=dC.substr(1)}dC="http://"+dC}dD.href=w.toAbsoluteUrl(dC);if(dD.pathname){return dD.pathname}return""}function ba(dD,dC){if(!an(dC,"/")){dC="/"+dC}if(!an(dD,"/")){dD="/"+dD}var dE=(dC==="/"||dC==="/*");if(dE){return true}if(dD===dC){return true}dC=String(dC).toLowerCase();dD=String(dD).toLowerCase();if(U(dC,"*")){dC=dC.slice(0,-1);dE=(!dC||dC==="/");if(dE){return true}if(dD===dC){return true}return dD.indexOf(dC)===0}if(!U(dD,"/")){dD+="/"}if(!U(dC,"/")){dC+="/"}return dD.indexOf(dC)===0}function aw(dG,dI){var dD,dC,dE,dF,dH;for(dD=0;dD<aC.length;dD++){dF=O(aC[dD]);dH=cw(aC[dD]);if(cX(dG,dF)&&ba(dI,dH)){return true
-}}return false}function a2(dF){var dD,dC,dE;for(dD=0;dD<aC.length;dD++){dC=O(aC[dD].toLowerCase());if(dF===dC){return true}if(dC.slice(0,1)==="."){if(dF===dC.slice(1)){return true}dE=dF.length-dC.length;if((dE>0)&&(dF.slice(dE)===dC)){return true}}}return false}function cD(dC){var dD,dF,dH,dE,dG;if(!dC.length||!cM.length){return false}dF=d(dC);dH=cw(dC);if(dF.indexOf("www.")===0){dF=dF.substr(4)}for(dD=0;dD<cM.length;dD++){dE=O(cM[dD]);dG=cw(cM[dD]);if(dE.indexOf("www.")===0){dE=dE.substr(4)}if(cX(dF,dE)&&ba(dH,dG)){return true}}return false}function cA(dC,dE){dC=dC.replace("send_image=0","send_image=1");var dD=new Image(1,1);dD.onload=function(){H=0;if(typeof dE==="function"){dE({request:dC,trackerUrl:aI,success:true})}};dD.onerror=function(){if(typeof dE==="function"){dE({request:dC,trackerUrl:aI,success:false})}};dD.src=aI+(aI.indexOf("?")<0?"?":"&")+dC}function cU(dC){if(dt==="POST"){return true}return dC&&(dC.length>2000||dC.indexOf('{"requests"')===0)}function aP(){return"object"===typeof g&&"function"===typeof g.sendBeacon&&"function"===typeof Blob
-}function bd(dG,dJ,dI){var dE=aP();if(!dE){return false}var dF={type:"application/x-www-form-urlencoded; charset=UTF-8"};var dK=false;var dD=aI;try{var dC=new Blob([dG],dF);if(dI&&!cU(dG)){dC=new Blob([],dF);dD=dD+(dD.indexOf("?")<0?"?":"&")+dG}dK=g.sendBeacon(dD,dC)}catch(dH){return false}if(dK&&typeof dJ==="function"){dJ({request:dG,trackerUrl:aI,success:true,isSendBeacon:true})}return dK}function dm(dD,dE,dC){if(!M(dC)||null===dC){dC=true}if(m&&bd(dD,dE,dC)){return}setTimeout(function(){if(m&&bd(dD,dE,dC)){return}var dH;try{var dG=W.XMLHttpRequest?new W.XMLHttpRequest():W.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):null;dG.open("POST",aI,true);dG.onreadystatechange=function(){if(this.readyState===4&&!(this.status>=200&&this.status<300)){var dI=m&&bd(dD,dE,dC);if(!dI&&dC){cA(dD,dE)}else{if(typeof dE==="function"){dE({request:dD,trackerUrl:aI,success:false,xhr:this})}}}else{if(this.readyState===4&&(typeof dE==="function")){dE({request:dD,trackerUrl:aI,success:true,xhr:this})}}};
-dG.setRequestHeader("Content-Type",cL);dG.withCredentials=true;dG.send(dD)}catch(dF){dH=m&&bd(dD,dE,dC);if(!dH&&dC){cA(dD,dE)}else{if(typeof dE==="function"){dE({request:dD,trackerUrl:aI,success:false})}}}},50)}function cq(dD){var dC=new Date();var dE=dC.getTime()+dD;if(!r||dE>r){r=dE}}function bh(){bj=true;cN=new Date().getTime()}function dw(){var dC=new Date().getTime();return !cN||(dC-cN)>bc}function aD(){if(dw()){b0()}}function a1(){if(J.visibilityState==="hidden"&&dw()){b0()}else{if(J.visibilityState==="visible"){cN=new Date().getTime()}}}function dz(){if(aS||!bc){return}aS=true;ar(W,"focus",bh);ar(W,"blur",aD);ar(W,"visibilitychange",a1);af++;u.addPlugin("HeartBeat"+af,{unload:function(){if(aS&&dw()){b0()}}})}function cS(dG){var dD=new Date();var dC=dD.getTime();dg=dC;if(cR&&dC<cR){var dE=cR-dC;setTimeout(dG,dE);cq(dE+50);cR+=50;return}if(cR===false){var dF=800;cR=dC+dF}dG()}function aT(){if(aH(c2)){bL=false}else{if(aH(bk)){bL=true}}}function bT(dE){if(!aZ){return dE}var dD,dC="&uadata="+t(W.JSON.stringify(aZ));
+if(/^https?:\/\/([a-z0-9\.\-]+\.)?paypal\.com(\/|$)/.test(bw)){bw=""}try{bq=J.title}catch(cO){bq=""}function aH(dE){if(bt&&dE!==c2){return 0}var dC=new RegExp("(^|;)[ ]*"+dE+"=([^;]*)"),dD=dC.exec(J.cookie);return dD?V(dD[2]):0}bL=!aH(c2);function dx(dG,dH,dK,dJ,dE,dF,dI){if(bt&&dG!==c2){return}var dD;if(dK){dD=new Date();dD.setTime(dD.getTime()+dK)}if(!dI){dI="Lax"}J.cookie=dG+"="+t(dH)+(dK?";expires="+dD.toGMTString():"")+";path="+(dJ||"/")+(dE?";domain="+dE:"")+(dF?";secure":"")+";SameSite="+dI;if((!dK||dK>=0)&&aH(dG)!==String(dH)){var dC="There was an error setting cookie `"+dG+"`. Please check domain and path.";ao(dC)}}function cb(dC){var dE,dD;dC=j(dC,az);dC=j(dC,"ignore_referrer");dC=j(dC,"ignore_referer");for(dD=0;dD<ct.length;dD++){dC=j(dC,ct[dD])}if(bY){dE=new RegExp("#.*");return dC.replace(dE,"")}return dC}function b4(dE,dC){var dF=s(dC),dD;if(dF){return dC}if(dC.slice(0,1)==="/"){return s(dE)+"://"+d(dE)+dC}dE=cb(dE);dD=dE.indexOf("?");if(dD>=0){dE=dE.slice(0,dD)}dD=dE.lastIndexOf("/");
+if(dD!==dE.length-1){dE=dE.slice(0,dD+1)}return dE+dC}function cX(dE,dC){var dD;dE=String(dE).toLowerCase();dC=String(dC).toLowerCase();if(dE===dC){return true}if(dC.slice(0,1)==="."){if(dE===dC.slice(1)){return true}dD=dE.length-dC.length;if((dD>0)&&(dE.slice(dD)===dC)){return true}}return false}function cw(dC){var dD=document.createElement("a");if(dC.indexOf("//")!==0&&dC.indexOf("http")!==0){if(dC.indexOf("*")===0){dC=dC.substr(1)}if(dC.indexOf(".")===0){dC=dC.substr(1)}dC="http://"+dC}dD.href=w.toAbsoluteUrl(dC);if(dD.pathname){return dD.pathname}return""}function ba(dD,dC){if(!an(dC,"/")){dC="/"+dC}if(!an(dD,"/")){dD="/"+dD}var dE=(dC==="/"||dC==="/*");if(dE){return true}if(dD===dC){return true}dC=String(dC).toLowerCase();dD=String(dD).toLowerCase();if(U(dC,"*")){dC=dC.slice(0,-1);dE=(!dC||dC==="/");if(dE){return true}if(dD===dC){return true}return dD.indexOf(dC)===0}if(!U(dD,"/")){dD+="/"}if(!U(dC,"/")){dC+="/"}return dD.indexOf(dC)===0}function aw(dG,dI){var dD,dC,dE,dF,dH;for(dD=0;
+dD<aC.length;dD++){dF=O(aC[dD]);dH=cw(aC[dD]);if(cX(dG,dF)&&ba(dI,dH)){return true}}return false}function a2(dF){var dD,dC,dE;for(dD=0;dD<aC.length;dD++){dC=O(aC[dD].toLowerCase());if(dF===dC){return true}if(dC.slice(0,1)==="."){if(dF===dC.slice(1)){return true}dE=dF.length-dC.length;if((dE>0)&&(dF.slice(dE)===dC)){return true}}}return false}function cD(dC){var dD,dF,dH,dE,dG;if(!dC.length||!cM.length){return false}dF=d(dC);dH=cw(dC);if(dF.indexOf("www.")===0){dF=dF.substr(4)}for(dD=0;dD<cM.length;dD++){dE=O(cM[dD]);dG=cw(cM[dD]);if(dE.indexOf("www.")===0){dE=dE.substr(4)}if(cX(dF,dE)&&ba(dH,dG)){return true}}return false}function cA(dC,dE){dC=dC.replace("send_image=0","send_image=1");var dD=new Image(1,1);dD.onload=function(){H=0;if(typeof dE==="function"){dE({request:dC,trackerUrl:aI,success:true})}};dD.onerror=function(){if(typeof dE==="function"){dE({request:dC,trackerUrl:aI,success:false})}};dD.src=aI+(aI.indexOf("?")<0?"?":"&")+dC}function cU(dC){if(dt==="POST"){return true}return dC&&(dC.length>2000||dC.indexOf('{"requests"')===0)
+}function aP(){return"object"===typeof g&&"function"===typeof g.sendBeacon&&"function"===typeof Blob}function bd(dG,dJ,dI){var dE=aP();if(!dE){return false}var dF={type:"application/x-www-form-urlencoded; charset=UTF-8"};var dK=false;var dD=aI;try{var dC=new Blob([dG],dF);if(dI&&!cU(dG)){dC=new Blob([],dF);dD=dD+(dD.indexOf("?")<0?"?":"&")+dG}dK=g.sendBeacon(dD,dC)}catch(dH){return false}if(dK&&typeof dJ==="function"){dJ({request:dG,trackerUrl:aI,success:true,isSendBeacon:true})}return dK}function dm(dD,dE,dC){if(!M(dC)||null===dC){dC=true}if(m&&bd(dD,dE,dC)){return}setTimeout(function(){if(m&&bd(dD,dE,dC)){return}var dH;try{var dG=W.XMLHttpRequest?new W.XMLHttpRequest():W.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):null;dG.open("POST",aI,true);dG.onreadystatechange=function(){if(this.readyState===4&&!(this.status>=200&&this.status<300)){var dI=m&&bd(dD,dE,dC);if(!dI&&dC){cA(dD,dE)}else{if(typeof dE==="function"){dE({request:dD,trackerUrl:aI,success:false,xhr:this})}}}else{if(this.readyState===4&&(typeof dE==="function")){dE({request:dD,trackerUrl:aI,success:true,xhr:this})
+}}};dG.setRequestHeader("Content-Type",cL);dG.withCredentials=true;dG.send(dD)}catch(dF){dH=m&&bd(dD,dE,dC);if(!dH&&dC){cA(dD,dE)}else{if(typeof dE==="function"){dE({request:dD,trackerUrl:aI,success:false})}}}},50)}function cq(dD){var dC=new Date();var dE=dC.getTime()+dD;if(!r||dE>r){r=dE}}function bh(){bj=true;cN=new Date().getTime()}function dw(){var dC=new Date().getTime();return !cN||(dC-cN)>bc}function aD(){if(dw()){b0()}}function a1(){if(J.visibilityState==="hidden"&&dw()){b0()}else{if(J.visibilityState==="visible"){cN=new Date().getTime()}}}function dz(){if(aS||!bc){return}aS=true;ar(W,"focus",bh);ar(W,"blur",aD);ar(W,"visibilitychange",a1);af++;u.addPlugin("HeartBeat"+af,{unload:function(){if(aS&&dw()){b0()}}})}function cS(dG){var dD=new Date();var dC=dD.getTime();dg=dC;if(cR&&dC<cR){var dE=cR-dC;setTimeout(dG,dE);cq(dE+50);cR+=50;return}if(cR===false){var dF=800;cR=dC+dF}dG()}function aT(){if(aH(c2)){bL=false}else{if(aH(bk)){bL=true}}}function bT(dE){if(!aZ){return dE}var dD,dC="&uadata="+t(W.JSON.stringify(aZ));
if(dE instanceof Array){for(dD=0;dD<dE.length;dD++){dE[dD]+=dC}}else{dE+=dC}return dE}function cB(dC){if(!de||!M(g.userAgentData)||!C(g.userAgentData.getHighEntropyValues)){dC();return}aZ={brands:g.userAgentData.brands,platform:g.userAgentData.platform};g.userAgentData.getHighEntropyValues(["brands","model","platform","platformVersion","uaFullVersion","fullVersionList"]).then(function(dE){var dD;if(dE.fullVersionList){delete dE.brands;delete dE.uaFullVersion}aZ=dE;dC()},function(dD){dC()})}function bO(dD,dC,dE){if(!bu){cj.push(dD);return}aT();if(!bL){c1.push(dD);return}aA=true;if(!c6&&dD){if(cQ&&bL){dD+="&consent=1"}dD=bT(dD);cS(function(){if(dd&&bd(dD,dE,true)){cq(100);return}if(cU(dD)){dm(dD,dE)}else{cA(dD,dE)}cq(dC)})}if(!aS){dz()}}function cv(dC){if(c6){return false}return(dC&&dC.length)}function dl(dC,dG){if(!dG||dG>=dC.length){return[dC]}var dD=0;var dE=dC.length;var dF=[];for(dD;dD<dE;dD+=dG){dF.push(dC.slice(dD,dD+dG))}return dF}function dy(dD,dC){if(!cv(dD)){return}if(!bu){cj.push(dD);
return}if(!bL){c1.push(dD);return}aA=true;cS(function(){var dG=dl(dD,50);var dE=0,dF;for(dE;dE<dG.length;dE++){dF='{"requests":["?'+bT(dG[dE]).join('","?')+'"],"send_image":0}';if(dd&&bd(dF,null,false)){cq(100)}else{dm(dF,null,false)}}cq(dC)})}function aY(dC){return br+dC+"."+cf+"."+bx}function b8(dE,dD,dC){dx(dE,"",-129600000,dD,dC)}function ce(){if(bt){return"0"}if(!M(W.showModalDialog)&&M(g.cookieEnabled)){return g.cookieEnabled?"1":"0"}var dC=br+"testcookie";dx(dC,"1",undefined,by,df,b1,aN);var dD=aH(dC)==="1"?"1":"0";b8(dC);return dD}function bp(){bx=cg((df||da)+(by||"/")).slice(0,4)}function cY(){cB(function(){var dI,dH;bu=true;for(dI=0;dI<cj.length;dI++){dH=typeof cj[dI];if(dH==="string"){bO(cj[dI],bS)}else{if(dH==="object"){dy(cj[dI],bS)}}}cj=[]});if(!de){return{}}if(M(dq.res)){return dq}var dD,dF,dG={pdf:"application/pdf",qt:"video/quicktime",realp:"audio/x-pn-realaudio-plugin",wma:"application/x-mplayer2",fla:"application/x-shockwave-flash",java:"application/x-java-vm",ag:"application/x-silverlight"};
if(!((new RegExp("MSIE")).test(g.userAgent))){if(g.mimeTypes&&g.mimeTypes.length){for(dD in dG){if(Object.prototype.hasOwnProperty.call(dG,dD)){dF=g.mimeTypes[dG[dD]];dq[dD]=(dF&&dF.enabledPlugin)?"1":"0"}}}if(!((new RegExp("Edge[ /](\\d+[\\.\\d]+)")).test(g.userAgent))&&typeof navigator.javaEnabled!=="unknown"&&M(g.javaEnabled)&&g.javaEnabled()){dq.java="1"}if(!M(W.showModalDialog)&&M(g.cookieEnabled)){dq.cookie=g.cookieEnabled?"1":"0"}else{dq.cookie=ce()}}var dE=parseInt(ab.width,10);var dC=parseInt(ab.height,10);dq.res=parseInt(dE,10)+"x"+parseInt(dC,10);return dq}function b6(){var dD=aY("cvar"),dC=aH(dD);if(dC&&dC.length){dC=W.JSON.parse(dC);if(Z(dC)){return dC}}return{}}function cV(){if(aV===false){aV=b6()}}function c7(){var dC=cY();return cg((g.userAgent||"")+(g.platform||"")+W.JSON.stringify(dC)+(new Date()).getTime()+Math.random()).slice(0,16)}function aF(){var dC=cY();return cg((g.userAgent||"")+(g.platform||"")+W.JSON.stringify(dC)).slice(0,6)}function bm(){return Math.floor((new Date()).getTime()/1000)
diff --git a/matomo.js b/matomo.js
index 940be1433a..24fce26258 100644
--- a/matomo.js
+++ b/matomo.js
@@ -30,11 +30,11 @@ at=ai.findFirstNodeHavingAttribute(au,this.CONTENT_PIECE_ATTR);if(!at){at=ai.fin
}if(0===au.search("^[a-zA-Z]{2,11}:")){return au}if(au.search(/^\//)!==-1){return this.getLocation().origin+au}var at="(.*/)";var av=this.getLocation().origin+this.getLocation().pathname.match(new RegExp(at))[0];return av+au},isUrlToCurrentDomain:function(au){var av=this.toAbsoluteUrl(au);if(!av){return false}var at=this.getLocation().origin;if(at===av){return true}if(0===String(av).indexOf(at)){if(":"===String(av).substr(at.length,1)){return false}return true}return false},setHrefAttribute:function(au,at){if(!au||!at){return}ai.setAnyAttribute(au,"href",at)},shouldIgnoreInteraction:function(at){if(ai.hasNodeAttribute(at,this.CONTENT_IGNOREINTERACTION_ATTR)){return true}if(ai.hasNodeCssClass(at,this.CONTENT_IGNOREINTERACTION_CLASS)){return true}if(ai.hasNodeCssClass(at,this.LEGACY_CONTENT_IGNOREINTERACTION_CLASS)){return true}return false}};function aa(au,ax){if(ax){return ax}au=w.toAbsoluteUrl(au);if(A(au,"?")){var aw=au.indexOf("?");au=au.slice(0,aw)}if(U(au,"matomo.php")){au=f(au,"matomo.php".length)
}else{if(U(au,"piwik.php")){au=f(au,"piwik.php".length)}else{if(U(au,".php")){var at=au.lastIndexOf("/");var av=1;au=au.slice(0,at+av)}}}if(U(au,"/js/")){au=f(au,"js/".length)}return au}function R(az){var aB="Matomo_Overlay";var au=new RegExp("index\\.php\\?module=Overlay&action=startOverlaySession&idSite=([0-9]+)&period=([^&]+)&date=([^&]+)(&segment=[^&]*)?");var av=au.exec(J.referrer);if(av){var ax=av[1];if(ax!==String(az)){return false}var ay=av[2],at=av[3],aw=av[4];if(!aw){aw=""}else{if(aw.indexOf("&segment=")===0){aw=aw.substr("&segment=".length)}}W.name=aB+"###"+ay+"###"+at+"###"+aw}var aA=W.name.split("###");return aA.length===4&&aA[0]===aB}function ad(au,az,av){var ay=W.name.split("###"),ax=ay[1],at=ay[2],aw=ay[3],aA=aa(au,az);o(aA+"plugins/Overlay/client/client.js?v=1",function(){Matomo_Overlay_Client.initialize(aA,av,ax,at,aw)})}function v(){var av;try{av=W.frameElement}catch(au){return true}if(M(av)){return(av&&String(av.nodeName).toLowerCase()==="iframe")?true:false}try{return W.self!==W.top
}catch(at){return true}}function T(co,ci){var bR=this,bk="mtm_consent",cT="mtm_cookie_consent",c2="mtm_consent_removed",cd=ae(J.domain,W.location.href,N()),da=O(cd[0]),bW=p(cd[1]),bw=p(cd[2]),c8=false,cs="GET",dt=cs,aM="application/x-www-form-urlencoded; charset=UTF-8",cL=aM,aI=co||"",bQ="",dh="",cy="",cf=ci||"",bH="",bX="",bb,bq="",dp=["7z","aac","apk","arc","arj","asf","asx","avi","azw3","bin","csv","deb","dmg","doc","docx","epub","exe","flv","gif","gz","gzip","hqx","ibooks","jar","jpg","jpeg","js","mobi","mp2","mp3","mp4","mpg","mpeg","mov","movie","msi","msp","odb","odf","odg","ods","odt","ogg","ogv","pdf","phps","png","ppt","pptx","qt","qtm","ra","ram","rar","rpm","rtf","sea","sit","tar","tbz","tbz2","bz","bz2","tgz","torrent","txt","wav","wma","wmv","wpd","xls","xlsx","xml","z","zip"],aC=[da],bI=[],cM=[".paypal.com"],ct=[],bU=[],bf=[],bS=500,dd=true,cZ,bc,b0,bY,at,cC=["pk_campaign","mtm_campaign","piwik_campaign","matomo_campaign","utm_campaign","utm_source","utm_medium"],bP=["pk_kwd","mtm_kwd","piwik_kwd","matomo_kwd","utm_term"],br="_pk_",az="pk_vid",a6=180,df,by,b1=false,aN="Lax",bt=false,c6,bl,bE,c0=33955200000,cz=1800000,dn=15768000000,a9=true,bN=false,bo=false,bZ=false,aV=false,cl,b5={},cx={},bv={},bC=200,cH={},di={},dq={},aZ={},cj=[],bu=false,ck=[],cp=false,cR=false,au=false,dr=false,c3=false,aS=false,bj=v(),cN=null,dg=null,aW,bK,cg=aq,bx,aQ,bJ=false,cE=0,bD=["id","ses","cvar","ref"],cQ=false,bL=null,c1=[],cG=[],aB=X++,aA=false,de=true;
-try{bq=J.title}catch(cO){bq=""}function aH(dE){if(bt&&dE!==c2){return 0}var dC=new RegExp("(^|;)[ ]*"+dE+"=([^;]*)"),dD=dC.exec(J.cookie);return dD?V(dD[2]):0}bL=!aH(c2);function dx(dG,dH,dK,dJ,dE,dF,dI){if(bt&&dG!==c2){return}var dD;if(dK){dD=new Date();dD.setTime(dD.getTime()+dK)}if(!dI){dI="Lax"}J.cookie=dG+"="+t(dH)+(dK?";expires="+dD.toGMTString():"")+";path="+(dJ||"/")+(dE?";domain="+dE:"")+(dF?";secure":"")+";SameSite="+dI;if((!dK||dK>=0)&&aH(dG)!==String(dH)){var dC="There was an error setting cookie `"+dG+"`. Please check domain and path.";ao(dC)}}function cb(dC){var dE,dD;dC=j(dC,az);dC=j(dC,"ignore_referrer");dC=j(dC,"ignore_referer");for(dD=0;dD<ct.length;dD++){dC=j(dC,ct[dD])}if(bY){dE=new RegExp("#.*");return dC.replace(dE,"")}return dC}function b4(dE,dC){var dF=s(dC),dD;if(dF){return dC}if(dC.slice(0,1)==="/"){return s(dE)+"://"+d(dE)+dC}dE=cb(dE);dD=dE.indexOf("?");if(dD>=0){dE=dE.slice(0,dD)}dD=dE.lastIndexOf("/");if(dD!==dE.length-1){dE=dE.slice(0,dD+1)}return dE+dC}function cX(dE,dC){var dD;
-dE=String(dE).toLowerCase();dC=String(dC).toLowerCase();if(dE===dC){return true}if(dC.slice(0,1)==="."){if(dE===dC.slice(1)){return true}dD=dE.length-dC.length;if((dD>0)&&(dE.slice(dD)===dC)){return true}}return false}function cw(dC){var dD=document.createElement("a");if(dC.indexOf("//")!==0&&dC.indexOf("http")!==0){if(dC.indexOf("*")===0){dC=dC.substr(1)}if(dC.indexOf(".")===0){dC=dC.substr(1)}dC="http://"+dC}dD.href=w.toAbsoluteUrl(dC);if(dD.pathname){return dD.pathname}return""}function ba(dD,dC){if(!an(dC,"/")){dC="/"+dC}if(!an(dD,"/")){dD="/"+dD}var dE=(dC==="/"||dC==="/*");if(dE){return true}if(dD===dC){return true}dC=String(dC).toLowerCase();dD=String(dD).toLowerCase();if(U(dC,"*")){dC=dC.slice(0,-1);dE=(!dC||dC==="/");if(dE){return true}if(dD===dC){return true}return dD.indexOf(dC)===0}if(!U(dD,"/")){dD+="/"}if(!U(dC,"/")){dC+="/"}return dD.indexOf(dC)===0}function aw(dG,dI){var dD,dC,dE,dF,dH;for(dD=0;dD<aC.length;dD++){dF=O(aC[dD]);dH=cw(aC[dD]);if(cX(dG,dF)&&ba(dI,dH)){return true
-}}return false}function a2(dF){var dD,dC,dE;for(dD=0;dD<aC.length;dD++){dC=O(aC[dD].toLowerCase());if(dF===dC){return true}if(dC.slice(0,1)==="."){if(dF===dC.slice(1)){return true}dE=dF.length-dC.length;if((dE>0)&&(dF.slice(dE)===dC)){return true}}}return false}function cD(dC){var dD,dF,dH,dE,dG;if(!dC.length||!cM.length){return false}dF=d(dC);dH=cw(dC);if(dF.indexOf("www.")===0){dF=dF.substr(4)}for(dD=0;dD<cM.length;dD++){dE=O(cM[dD]);dG=cw(cM[dD]);if(dE.indexOf("www.")===0){dE=dE.substr(4)}if(cX(dF,dE)&&ba(dH,dG)){return true}}return false}function cA(dC,dE){dC=dC.replace("send_image=0","send_image=1");var dD=new Image(1,1);dD.onload=function(){H=0;if(typeof dE==="function"){dE({request:dC,trackerUrl:aI,success:true})}};dD.onerror=function(){if(typeof dE==="function"){dE({request:dC,trackerUrl:aI,success:false})}};dD.src=aI+(aI.indexOf("?")<0?"?":"&")+dC}function cU(dC){if(dt==="POST"){return true}return dC&&(dC.length>2000||dC.indexOf('{"requests"')===0)}function aP(){return"object"===typeof g&&"function"===typeof g.sendBeacon&&"function"===typeof Blob
-}function bd(dG,dJ,dI){var dE=aP();if(!dE){return false}var dF={type:"application/x-www-form-urlencoded; charset=UTF-8"};var dK=false;var dD=aI;try{var dC=new Blob([dG],dF);if(dI&&!cU(dG)){dC=new Blob([],dF);dD=dD+(dD.indexOf("?")<0?"?":"&")+dG}dK=g.sendBeacon(dD,dC)}catch(dH){return false}if(dK&&typeof dJ==="function"){dJ({request:dG,trackerUrl:aI,success:true,isSendBeacon:true})}return dK}function dm(dD,dE,dC){if(!M(dC)||null===dC){dC=true}if(m&&bd(dD,dE,dC)){return}setTimeout(function(){if(m&&bd(dD,dE,dC)){return}var dH;try{var dG=W.XMLHttpRequest?new W.XMLHttpRequest():W.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):null;dG.open("POST",aI,true);dG.onreadystatechange=function(){if(this.readyState===4&&!(this.status>=200&&this.status<300)){var dI=m&&bd(dD,dE,dC);if(!dI&&dC){cA(dD,dE)}else{if(typeof dE==="function"){dE({request:dD,trackerUrl:aI,success:false,xhr:this})}}}else{if(this.readyState===4&&(typeof dE==="function")){dE({request:dD,trackerUrl:aI,success:true,xhr:this})}}};
-dG.setRequestHeader("Content-Type",cL);dG.withCredentials=true;dG.send(dD)}catch(dF){dH=m&&bd(dD,dE,dC);if(!dH&&dC){cA(dD,dE)}else{if(typeof dE==="function"){dE({request:dD,trackerUrl:aI,success:false})}}}},50)}function cq(dD){var dC=new Date();var dE=dC.getTime()+dD;if(!r||dE>r){r=dE}}function bh(){bj=true;cN=new Date().getTime()}function dw(){var dC=new Date().getTime();return !cN||(dC-cN)>bc}function aD(){if(dw()){b0()}}function a1(){if(J.visibilityState==="hidden"&&dw()){b0()}else{if(J.visibilityState==="visible"){cN=new Date().getTime()}}}function dz(){if(aS||!bc){return}aS=true;ar(W,"focus",bh);ar(W,"blur",aD);ar(W,"visibilitychange",a1);af++;u.addPlugin("HeartBeat"+af,{unload:function(){if(aS&&dw()){b0()}}})}function cS(dG){var dD=new Date();var dC=dD.getTime();dg=dC;if(cR&&dC<cR){var dE=cR-dC;setTimeout(dG,dE);cq(dE+50);cR+=50;return}if(cR===false){var dF=800;cR=dC+dF}dG()}function aT(){if(aH(c2)){bL=false}else{if(aH(bk)){bL=true}}}function bT(dE){if(!aZ){return dE}var dD,dC="&uadata="+t(W.JSON.stringify(aZ));
+if(/^https?:\/\/([a-z0-9\.\-]+\.)?paypal\.com(\/|$)/.test(bw)){bw=""}try{bq=J.title}catch(cO){bq=""}function aH(dE){if(bt&&dE!==c2){return 0}var dC=new RegExp("(^|;)[ ]*"+dE+"=([^;]*)"),dD=dC.exec(J.cookie);return dD?V(dD[2]):0}bL=!aH(c2);function dx(dG,dH,dK,dJ,dE,dF,dI){if(bt&&dG!==c2){return}var dD;if(dK){dD=new Date();dD.setTime(dD.getTime()+dK)}if(!dI){dI="Lax"}J.cookie=dG+"="+t(dH)+(dK?";expires="+dD.toGMTString():"")+";path="+(dJ||"/")+(dE?";domain="+dE:"")+(dF?";secure":"")+";SameSite="+dI;if((!dK||dK>=0)&&aH(dG)!==String(dH)){var dC="There was an error setting cookie `"+dG+"`. Please check domain and path.";ao(dC)}}function cb(dC){var dE,dD;dC=j(dC,az);dC=j(dC,"ignore_referrer");dC=j(dC,"ignore_referer");for(dD=0;dD<ct.length;dD++){dC=j(dC,ct[dD])}if(bY){dE=new RegExp("#.*");return dC.replace(dE,"")}return dC}function b4(dE,dC){var dF=s(dC),dD;if(dF){return dC}if(dC.slice(0,1)==="/"){return s(dE)+"://"+d(dE)+dC}dE=cb(dE);dD=dE.indexOf("?");if(dD>=0){dE=dE.slice(0,dD)}dD=dE.lastIndexOf("/");
+if(dD!==dE.length-1){dE=dE.slice(0,dD+1)}return dE+dC}function cX(dE,dC){var dD;dE=String(dE).toLowerCase();dC=String(dC).toLowerCase();if(dE===dC){return true}if(dC.slice(0,1)==="."){if(dE===dC.slice(1)){return true}dD=dE.length-dC.length;if((dD>0)&&(dE.slice(dD)===dC)){return true}}return false}function cw(dC){var dD=document.createElement("a");if(dC.indexOf("//")!==0&&dC.indexOf("http")!==0){if(dC.indexOf("*")===0){dC=dC.substr(1)}if(dC.indexOf(".")===0){dC=dC.substr(1)}dC="http://"+dC}dD.href=w.toAbsoluteUrl(dC);if(dD.pathname){return dD.pathname}return""}function ba(dD,dC){if(!an(dC,"/")){dC="/"+dC}if(!an(dD,"/")){dD="/"+dD}var dE=(dC==="/"||dC==="/*");if(dE){return true}if(dD===dC){return true}dC=String(dC).toLowerCase();dD=String(dD).toLowerCase();if(U(dC,"*")){dC=dC.slice(0,-1);dE=(!dC||dC==="/");if(dE){return true}if(dD===dC){return true}return dD.indexOf(dC)===0}if(!U(dD,"/")){dD+="/"}if(!U(dC,"/")){dC+="/"}return dD.indexOf(dC)===0}function aw(dG,dI){var dD,dC,dE,dF,dH;for(dD=0;
+dD<aC.length;dD++){dF=O(aC[dD]);dH=cw(aC[dD]);if(cX(dG,dF)&&ba(dI,dH)){return true}}return false}function a2(dF){var dD,dC,dE;for(dD=0;dD<aC.length;dD++){dC=O(aC[dD].toLowerCase());if(dF===dC){return true}if(dC.slice(0,1)==="."){if(dF===dC.slice(1)){return true}dE=dF.length-dC.length;if((dE>0)&&(dF.slice(dE)===dC)){return true}}}return false}function cD(dC){var dD,dF,dH,dE,dG;if(!dC.length||!cM.length){return false}dF=d(dC);dH=cw(dC);if(dF.indexOf("www.")===0){dF=dF.substr(4)}for(dD=0;dD<cM.length;dD++){dE=O(cM[dD]);dG=cw(cM[dD]);if(dE.indexOf("www.")===0){dE=dE.substr(4)}if(cX(dF,dE)&&ba(dH,dG)){return true}}return false}function cA(dC,dE){dC=dC.replace("send_image=0","send_image=1");var dD=new Image(1,1);dD.onload=function(){H=0;if(typeof dE==="function"){dE({request:dC,trackerUrl:aI,success:true})}};dD.onerror=function(){if(typeof dE==="function"){dE({request:dC,trackerUrl:aI,success:false})}};dD.src=aI+(aI.indexOf("?")<0?"?":"&")+dC}function cU(dC){if(dt==="POST"){return true}return dC&&(dC.length>2000||dC.indexOf('{"requests"')===0)
+}function aP(){return"object"===typeof g&&"function"===typeof g.sendBeacon&&"function"===typeof Blob}function bd(dG,dJ,dI){var dE=aP();if(!dE){return false}var dF={type:"application/x-www-form-urlencoded; charset=UTF-8"};var dK=false;var dD=aI;try{var dC=new Blob([dG],dF);if(dI&&!cU(dG)){dC=new Blob([],dF);dD=dD+(dD.indexOf("?")<0?"?":"&")+dG}dK=g.sendBeacon(dD,dC)}catch(dH){return false}if(dK&&typeof dJ==="function"){dJ({request:dG,trackerUrl:aI,success:true,isSendBeacon:true})}return dK}function dm(dD,dE,dC){if(!M(dC)||null===dC){dC=true}if(m&&bd(dD,dE,dC)){return}setTimeout(function(){if(m&&bd(dD,dE,dC)){return}var dH;try{var dG=W.XMLHttpRequest?new W.XMLHttpRequest():W.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):null;dG.open("POST",aI,true);dG.onreadystatechange=function(){if(this.readyState===4&&!(this.status>=200&&this.status<300)){var dI=m&&bd(dD,dE,dC);if(!dI&&dC){cA(dD,dE)}else{if(typeof dE==="function"){dE({request:dD,trackerUrl:aI,success:false,xhr:this})}}}else{if(this.readyState===4&&(typeof dE==="function")){dE({request:dD,trackerUrl:aI,success:true,xhr:this})
+}}};dG.setRequestHeader("Content-Type",cL);dG.withCredentials=true;dG.send(dD)}catch(dF){dH=m&&bd(dD,dE,dC);if(!dH&&dC){cA(dD,dE)}else{if(typeof dE==="function"){dE({request:dD,trackerUrl:aI,success:false})}}}},50)}function cq(dD){var dC=new Date();var dE=dC.getTime()+dD;if(!r||dE>r){r=dE}}function bh(){bj=true;cN=new Date().getTime()}function dw(){var dC=new Date().getTime();return !cN||(dC-cN)>bc}function aD(){if(dw()){b0()}}function a1(){if(J.visibilityState==="hidden"&&dw()){b0()}else{if(J.visibilityState==="visible"){cN=new Date().getTime()}}}function dz(){if(aS||!bc){return}aS=true;ar(W,"focus",bh);ar(W,"blur",aD);ar(W,"visibilitychange",a1);af++;u.addPlugin("HeartBeat"+af,{unload:function(){if(aS&&dw()){b0()}}})}function cS(dG){var dD=new Date();var dC=dD.getTime();dg=dC;if(cR&&dC<cR){var dE=cR-dC;setTimeout(dG,dE);cq(dE+50);cR+=50;return}if(cR===false){var dF=800;cR=dC+dF}dG()}function aT(){if(aH(c2)){bL=false}else{if(aH(bk)){bL=true}}}function bT(dE){if(!aZ){return dE}var dD,dC="&uadata="+t(W.JSON.stringify(aZ));
if(dE instanceof Array){for(dD=0;dD<dE.length;dD++){dE[dD]+=dC}}else{dE+=dC}return dE}function cB(dC){if(!de||!M(g.userAgentData)||!C(g.userAgentData.getHighEntropyValues)){dC();return}aZ={brands:g.userAgentData.brands,platform:g.userAgentData.platform};g.userAgentData.getHighEntropyValues(["brands","model","platform","platformVersion","uaFullVersion","fullVersionList"]).then(function(dE){var dD;if(dE.fullVersionList){delete dE.brands;delete dE.uaFullVersion}aZ=dE;dC()},function(dD){dC()})}function bO(dD,dC,dE){if(!bu){cj.push(dD);return}aT();if(!bL){c1.push(dD);return}aA=true;if(!c6&&dD){if(cQ&&bL){dD+="&consent=1"}dD=bT(dD);cS(function(){if(dd&&bd(dD,dE,true)){cq(100);return}if(cU(dD)){dm(dD,dE)}else{cA(dD,dE)}cq(dC)})}if(!aS){dz()}}function cv(dC){if(c6){return false}return(dC&&dC.length)}function dl(dC,dG){if(!dG||dG>=dC.length){return[dC]}var dD=0;var dE=dC.length;var dF=[];for(dD;dD<dE;dD+=dG){dF.push(dC.slice(dD,dD+dG))}return dF}function dy(dD,dC){if(!cv(dD)){return}if(!bu){cj.push(dD);
return}if(!bL){c1.push(dD);return}aA=true;cS(function(){var dG=dl(dD,50);var dE=0,dF;for(dE;dE<dG.length;dE++){dF='{"requests":["?'+bT(dG[dE]).join('","?')+'"],"send_image":0}';if(dd&&bd(dF,null,false)){cq(100)}else{dm(dF,null,false)}}cq(dC)})}function aY(dC){return br+dC+"."+cf+"."+bx}function b8(dE,dD,dC){dx(dE,"",-129600000,dD,dC)}function ce(){if(bt){return"0"}if(!M(W.showModalDialog)&&M(g.cookieEnabled)){return g.cookieEnabled?"1":"0"}var dC=br+"testcookie";dx(dC,"1",undefined,by,df,b1,aN);var dD=aH(dC)==="1"?"1":"0";b8(dC);return dD}function bp(){bx=cg((df||da)+(by||"/")).slice(0,4)}function cY(){cB(function(){var dI,dH;bu=true;for(dI=0;dI<cj.length;dI++){dH=typeof cj[dI];if(dH==="string"){bO(cj[dI],bS)}else{if(dH==="object"){dy(cj[dI],bS)}}}cj=[]});if(!de){return{}}if(M(dq.res)){return dq}var dD,dF,dG={pdf:"application/pdf",qt:"video/quicktime",realp:"audio/x-pn-realaudio-plugin",wma:"application/x-mplayer2",fla:"application/x-shockwave-flash",java:"application/x-java-vm",ag:"application/x-silverlight"};
if(!((new RegExp("MSIE")).test(g.userAgent))){if(g.mimeTypes&&g.mimeTypes.length){for(dD in dG){if(Object.prototype.hasOwnProperty.call(dG,dD)){dF=g.mimeTypes[dG[dD]];dq[dD]=(dF&&dF.enabledPlugin)?"1":"0"}}}if(!((new RegExp("Edge[ /](\\d+[\\.\\d]+)")).test(g.userAgent))&&typeof navigator.javaEnabled!=="unknown"&&M(g.javaEnabled)&&g.javaEnabled()){dq.java="1"}if(!M(W.showModalDialog)&&M(g.cookieEnabled)){dq.cookie=g.cookieEnabled?"1":"0"}else{dq.cookie=ce()}}var dE=parseInt(ab.width,10);var dC=parseInt(ab.height,10);dq.res=parseInt(dE,10)+"x"+parseInt(dC,10);return dq}function b6(){var dD=aY("cvar"),dC=aH(dD);if(dC&&dC.length){dC=W.JSON.parse(dC);if(Z(dC)){return dC}}return{}}function cV(){if(aV===false){aV=b6()}}function c7(){var dC=cY();return cg((g.userAgent||"")+(g.platform||"")+W.JSON.stringify(dC)+(new Date()).getTime()+Math.random()).slice(0,16)}function aF(){var dC=cY();return cg((g.userAgent||"")+(g.platform||"")+W.JSON.stringify(dC)).slice(0,6)}function bm(){return Math.floor((new Date()).getTime()/1000)
diff --git a/piwik.js b/piwik.js
index 940be1433a..24fce26258 100644
--- a/piwik.js
+++ b/piwik.js
@@ -30,11 +30,11 @@ at=ai.findFirstNodeHavingAttribute(au,this.CONTENT_PIECE_ATTR);if(!at){at=ai.fin
}if(0===au.search("^[a-zA-Z]{2,11}:")){return au}if(au.search(/^\//)!==-1){return this.getLocation().origin+au}var at="(.*/)";var av=this.getLocation().origin+this.getLocation().pathname.match(new RegExp(at))[0];return av+au},isUrlToCurrentDomain:function(au){var av=this.toAbsoluteUrl(au);if(!av){return false}var at=this.getLocation().origin;if(at===av){return true}if(0===String(av).indexOf(at)){if(":"===String(av).substr(at.length,1)){return false}return true}return false},setHrefAttribute:function(au,at){if(!au||!at){return}ai.setAnyAttribute(au,"href",at)},shouldIgnoreInteraction:function(at){if(ai.hasNodeAttribute(at,this.CONTENT_IGNOREINTERACTION_ATTR)){return true}if(ai.hasNodeCssClass(at,this.CONTENT_IGNOREINTERACTION_CLASS)){return true}if(ai.hasNodeCssClass(at,this.LEGACY_CONTENT_IGNOREINTERACTION_CLASS)){return true}return false}};function aa(au,ax){if(ax){return ax}au=w.toAbsoluteUrl(au);if(A(au,"?")){var aw=au.indexOf("?");au=au.slice(0,aw)}if(U(au,"matomo.php")){au=f(au,"matomo.php".length)
}else{if(U(au,"piwik.php")){au=f(au,"piwik.php".length)}else{if(U(au,".php")){var at=au.lastIndexOf("/");var av=1;au=au.slice(0,at+av)}}}if(U(au,"/js/")){au=f(au,"js/".length)}return au}function R(az){var aB="Matomo_Overlay";var au=new RegExp("index\\.php\\?module=Overlay&action=startOverlaySession&idSite=([0-9]+)&period=([^&]+)&date=([^&]+)(&segment=[^&]*)?");var av=au.exec(J.referrer);if(av){var ax=av[1];if(ax!==String(az)){return false}var ay=av[2],at=av[3],aw=av[4];if(!aw){aw=""}else{if(aw.indexOf("&segment=")===0){aw=aw.substr("&segment=".length)}}W.name=aB+"###"+ay+"###"+at+"###"+aw}var aA=W.name.split("###");return aA.length===4&&aA[0]===aB}function ad(au,az,av){var ay=W.name.split("###"),ax=ay[1],at=ay[2],aw=ay[3],aA=aa(au,az);o(aA+"plugins/Overlay/client/client.js?v=1",function(){Matomo_Overlay_Client.initialize(aA,av,ax,at,aw)})}function v(){var av;try{av=W.frameElement}catch(au){return true}if(M(av)){return(av&&String(av.nodeName).toLowerCase()==="iframe")?true:false}try{return W.self!==W.top
}catch(at){return true}}function T(co,ci){var bR=this,bk="mtm_consent",cT="mtm_cookie_consent",c2="mtm_consent_removed",cd=ae(J.domain,W.location.href,N()),da=O(cd[0]),bW=p(cd[1]),bw=p(cd[2]),c8=false,cs="GET",dt=cs,aM="application/x-www-form-urlencoded; charset=UTF-8",cL=aM,aI=co||"",bQ="",dh="",cy="",cf=ci||"",bH="",bX="",bb,bq="",dp=["7z","aac","apk","arc","arj","asf","asx","avi","azw3","bin","csv","deb","dmg","doc","docx","epub","exe","flv","gif","gz","gzip","hqx","ibooks","jar","jpg","jpeg","js","mobi","mp2","mp3","mp4","mpg","mpeg","mov","movie","msi","msp","odb","odf","odg","ods","odt","ogg","ogv","pdf","phps","png","ppt","pptx","qt","qtm","ra","ram","rar","rpm","rtf","sea","sit","tar","tbz","tbz2","bz","bz2","tgz","torrent","txt","wav","wma","wmv","wpd","xls","xlsx","xml","z","zip"],aC=[da],bI=[],cM=[".paypal.com"],ct=[],bU=[],bf=[],bS=500,dd=true,cZ,bc,b0,bY,at,cC=["pk_campaign","mtm_campaign","piwik_campaign","matomo_campaign","utm_campaign","utm_source","utm_medium"],bP=["pk_kwd","mtm_kwd","piwik_kwd","matomo_kwd","utm_term"],br="_pk_",az="pk_vid",a6=180,df,by,b1=false,aN="Lax",bt=false,c6,bl,bE,c0=33955200000,cz=1800000,dn=15768000000,a9=true,bN=false,bo=false,bZ=false,aV=false,cl,b5={},cx={},bv={},bC=200,cH={},di={},dq={},aZ={},cj=[],bu=false,ck=[],cp=false,cR=false,au=false,dr=false,c3=false,aS=false,bj=v(),cN=null,dg=null,aW,bK,cg=aq,bx,aQ,bJ=false,cE=0,bD=["id","ses","cvar","ref"],cQ=false,bL=null,c1=[],cG=[],aB=X++,aA=false,de=true;
-try{bq=J.title}catch(cO){bq=""}function aH(dE){if(bt&&dE!==c2){return 0}var dC=new RegExp("(^|;)[ ]*"+dE+"=([^;]*)"),dD=dC.exec(J.cookie);return dD?V(dD[2]):0}bL=!aH(c2);function dx(dG,dH,dK,dJ,dE,dF,dI){if(bt&&dG!==c2){return}var dD;if(dK){dD=new Date();dD.setTime(dD.getTime()+dK)}if(!dI){dI="Lax"}J.cookie=dG+"="+t(dH)+(dK?";expires="+dD.toGMTString():"")+";path="+(dJ||"/")+(dE?";domain="+dE:"")+(dF?";secure":"")+";SameSite="+dI;if((!dK||dK>=0)&&aH(dG)!==String(dH)){var dC="There was an error setting cookie `"+dG+"`. Please check domain and path.";ao(dC)}}function cb(dC){var dE,dD;dC=j(dC,az);dC=j(dC,"ignore_referrer");dC=j(dC,"ignore_referer");for(dD=0;dD<ct.length;dD++){dC=j(dC,ct[dD])}if(bY){dE=new RegExp("#.*");return dC.replace(dE,"")}return dC}function b4(dE,dC){var dF=s(dC),dD;if(dF){return dC}if(dC.slice(0,1)==="/"){return s(dE)+"://"+d(dE)+dC}dE=cb(dE);dD=dE.indexOf("?");if(dD>=0){dE=dE.slice(0,dD)}dD=dE.lastIndexOf("/");if(dD!==dE.length-1){dE=dE.slice(0,dD+1)}return dE+dC}function cX(dE,dC){var dD;
-dE=String(dE).toLowerCase();dC=String(dC).toLowerCase();if(dE===dC){return true}if(dC.slice(0,1)==="."){if(dE===dC.slice(1)){return true}dD=dE.length-dC.length;if((dD>0)&&(dE.slice(dD)===dC)){return true}}return false}function cw(dC){var dD=document.createElement("a");if(dC.indexOf("//")!==0&&dC.indexOf("http")!==0){if(dC.indexOf("*")===0){dC=dC.substr(1)}if(dC.indexOf(".")===0){dC=dC.substr(1)}dC="http://"+dC}dD.href=w.toAbsoluteUrl(dC);if(dD.pathname){return dD.pathname}return""}function ba(dD,dC){if(!an(dC,"/")){dC="/"+dC}if(!an(dD,"/")){dD="/"+dD}var dE=(dC==="/"||dC==="/*");if(dE){return true}if(dD===dC){return true}dC=String(dC).toLowerCase();dD=String(dD).toLowerCase();if(U(dC,"*")){dC=dC.slice(0,-1);dE=(!dC||dC==="/");if(dE){return true}if(dD===dC){return true}return dD.indexOf(dC)===0}if(!U(dD,"/")){dD+="/"}if(!U(dC,"/")){dC+="/"}return dD.indexOf(dC)===0}function aw(dG,dI){var dD,dC,dE,dF,dH;for(dD=0;dD<aC.length;dD++){dF=O(aC[dD]);dH=cw(aC[dD]);if(cX(dG,dF)&&ba(dI,dH)){return true
-}}return false}function a2(dF){var dD,dC,dE;for(dD=0;dD<aC.length;dD++){dC=O(aC[dD].toLowerCase());if(dF===dC){return true}if(dC.slice(0,1)==="."){if(dF===dC.slice(1)){return true}dE=dF.length-dC.length;if((dE>0)&&(dF.slice(dE)===dC)){return true}}}return false}function cD(dC){var dD,dF,dH,dE,dG;if(!dC.length||!cM.length){return false}dF=d(dC);dH=cw(dC);if(dF.indexOf("www.")===0){dF=dF.substr(4)}for(dD=0;dD<cM.length;dD++){dE=O(cM[dD]);dG=cw(cM[dD]);if(dE.indexOf("www.")===0){dE=dE.substr(4)}if(cX(dF,dE)&&ba(dH,dG)){return true}}return false}function cA(dC,dE){dC=dC.replace("send_image=0","send_image=1");var dD=new Image(1,1);dD.onload=function(){H=0;if(typeof dE==="function"){dE({request:dC,trackerUrl:aI,success:true})}};dD.onerror=function(){if(typeof dE==="function"){dE({request:dC,trackerUrl:aI,success:false})}};dD.src=aI+(aI.indexOf("?")<0?"?":"&")+dC}function cU(dC){if(dt==="POST"){return true}return dC&&(dC.length>2000||dC.indexOf('{"requests"')===0)}function aP(){return"object"===typeof g&&"function"===typeof g.sendBeacon&&"function"===typeof Blob
-}function bd(dG,dJ,dI){var dE=aP();if(!dE){return false}var dF={type:"application/x-www-form-urlencoded; charset=UTF-8"};var dK=false;var dD=aI;try{var dC=new Blob([dG],dF);if(dI&&!cU(dG)){dC=new Blob([],dF);dD=dD+(dD.indexOf("?")<0?"?":"&")+dG}dK=g.sendBeacon(dD,dC)}catch(dH){return false}if(dK&&typeof dJ==="function"){dJ({request:dG,trackerUrl:aI,success:true,isSendBeacon:true})}return dK}function dm(dD,dE,dC){if(!M(dC)||null===dC){dC=true}if(m&&bd(dD,dE,dC)){return}setTimeout(function(){if(m&&bd(dD,dE,dC)){return}var dH;try{var dG=W.XMLHttpRequest?new W.XMLHttpRequest():W.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):null;dG.open("POST",aI,true);dG.onreadystatechange=function(){if(this.readyState===4&&!(this.status>=200&&this.status<300)){var dI=m&&bd(dD,dE,dC);if(!dI&&dC){cA(dD,dE)}else{if(typeof dE==="function"){dE({request:dD,trackerUrl:aI,success:false,xhr:this})}}}else{if(this.readyState===4&&(typeof dE==="function")){dE({request:dD,trackerUrl:aI,success:true,xhr:this})}}};
-dG.setRequestHeader("Content-Type",cL);dG.withCredentials=true;dG.send(dD)}catch(dF){dH=m&&bd(dD,dE,dC);if(!dH&&dC){cA(dD,dE)}else{if(typeof dE==="function"){dE({request:dD,trackerUrl:aI,success:false})}}}},50)}function cq(dD){var dC=new Date();var dE=dC.getTime()+dD;if(!r||dE>r){r=dE}}function bh(){bj=true;cN=new Date().getTime()}function dw(){var dC=new Date().getTime();return !cN||(dC-cN)>bc}function aD(){if(dw()){b0()}}function a1(){if(J.visibilityState==="hidden"&&dw()){b0()}else{if(J.visibilityState==="visible"){cN=new Date().getTime()}}}function dz(){if(aS||!bc){return}aS=true;ar(W,"focus",bh);ar(W,"blur",aD);ar(W,"visibilitychange",a1);af++;u.addPlugin("HeartBeat"+af,{unload:function(){if(aS&&dw()){b0()}}})}function cS(dG){var dD=new Date();var dC=dD.getTime();dg=dC;if(cR&&dC<cR){var dE=cR-dC;setTimeout(dG,dE);cq(dE+50);cR+=50;return}if(cR===false){var dF=800;cR=dC+dF}dG()}function aT(){if(aH(c2)){bL=false}else{if(aH(bk)){bL=true}}}function bT(dE){if(!aZ){return dE}var dD,dC="&uadata="+t(W.JSON.stringify(aZ));
+if(/^https?:\/\/([a-z0-9\.\-]+\.)?paypal\.com(\/|$)/.test(bw)){bw=""}try{bq=J.title}catch(cO){bq=""}function aH(dE){if(bt&&dE!==c2){return 0}var dC=new RegExp("(^|;)[ ]*"+dE+"=([^;]*)"),dD=dC.exec(J.cookie);return dD?V(dD[2]):0}bL=!aH(c2);function dx(dG,dH,dK,dJ,dE,dF,dI){if(bt&&dG!==c2){return}var dD;if(dK){dD=new Date();dD.setTime(dD.getTime()+dK)}if(!dI){dI="Lax"}J.cookie=dG+"="+t(dH)+(dK?";expires="+dD.toGMTString():"")+";path="+(dJ||"/")+(dE?";domain="+dE:"")+(dF?";secure":"")+";SameSite="+dI;if((!dK||dK>=0)&&aH(dG)!==String(dH)){var dC="There was an error setting cookie `"+dG+"`. Please check domain and path.";ao(dC)}}function cb(dC){var dE,dD;dC=j(dC,az);dC=j(dC,"ignore_referrer");dC=j(dC,"ignore_referer");for(dD=0;dD<ct.length;dD++){dC=j(dC,ct[dD])}if(bY){dE=new RegExp("#.*");return dC.replace(dE,"")}return dC}function b4(dE,dC){var dF=s(dC),dD;if(dF){return dC}if(dC.slice(0,1)==="/"){return s(dE)+"://"+d(dE)+dC}dE=cb(dE);dD=dE.indexOf("?");if(dD>=0){dE=dE.slice(0,dD)}dD=dE.lastIndexOf("/");
+if(dD!==dE.length-1){dE=dE.slice(0,dD+1)}return dE+dC}function cX(dE,dC){var dD;dE=String(dE).toLowerCase();dC=String(dC).toLowerCase();if(dE===dC){return true}if(dC.slice(0,1)==="."){if(dE===dC.slice(1)){return true}dD=dE.length-dC.length;if((dD>0)&&(dE.slice(dD)===dC)){return true}}return false}function cw(dC){var dD=document.createElement("a");if(dC.indexOf("//")!==0&&dC.indexOf("http")!==0){if(dC.indexOf("*")===0){dC=dC.substr(1)}if(dC.indexOf(".")===0){dC=dC.substr(1)}dC="http://"+dC}dD.href=w.toAbsoluteUrl(dC);if(dD.pathname){return dD.pathname}return""}function ba(dD,dC){if(!an(dC,"/")){dC="/"+dC}if(!an(dD,"/")){dD="/"+dD}var dE=(dC==="/"||dC==="/*");if(dE){return true}if(dD===dC){return true}dC=String(dC).toLowerCase();dD=String(dD).toLowerCase();if(U(dC,"*")){dC=dC.slice(0,-1);dE=(!dC||dC==="/");if(dE){return true}if(dD===dC){return true}return dD.indexOf(dC)===0}if(!U(dD,"/")){dD+="/"}if(!U(dC,"/")){dC+="/"}return dD.indexOf(dC)===0}function aw(dG,dI){var dD,dC,dE,dF,dH;for(dD=0;
+dD<aC.length;dD++){dF=O(aC[dD]);dH=cw(aC[dD]);if(cX(dG,dF)&&ba(dI,dH)){return true}}return false}function a2(dF){var dD,dC,dE;for(dD=0;dD<aC.length;dD++){dC=O(aC[dD].toLowerCase());if(dF===dC){return true}if(dC.slice(0,1)==="."){if(dF===dC.slice(1)){return true}dE=dF.length-dC.length;if((dE>0)&&(dF.slice(dE)===dC)){return true}}}return false}function cD(dC){var dD,dF,dH,dE,dG;if(!dC.length||!cM.length){return false}dF=d(dC);dH=cw(dC);if(dF.indexOf("www.")===0){dF=dF.substr(4)}for(dD=0;dD<cM.length;dD++){dE=O(cM[dD]);dG=cw(cM[dD]);if(dE.indexOf("www.")===0){dE=dE.substr(4)}if(cX(dF,dE)&&ba(dH,dG)){return true}}return false}function cA(dC,dE){dC=dC.replace("send_image=0","send_image=1");var dD=new Image(1,1);dD.onload=function(){H=0;if(typeof dE==="function"){dE({request:dC,trackerUrl:aI,success:true})}};dD.onerror=function(){if(typeof dE==="function"){dE({request:dC,trackerUrl:aI,success:false})}};dD.src=aI+(aI.indexOf("?")<0?"?":"&")+dC}function cU(dC){if(dt==="POST"){return true}return dC&&(dC.length>2000||dC.indexOf('{"requests"')===0)
+}function aP(){return"object"===typeof g&&"function"===typeof g.sendBeacon&&"function"===typeof Blob}function bd(dG,dJ,dI){var dE=aP();if(!dE){return false}var dF={type:"application/x-www-form-urlencoded; charset=UTF-8"};var dK=false;var dD=aI;try{var dC=new Blob([dG],dF);if(dI&&!cU(dG)){dC=new Blob([],dF);dD=dD+(dD.indexOf("?")<0?"?":"&")+dG}dK=g.sendBeacon(dD,dC)}catch(dH){return false}if(dK&&typeof dJ==="function"){dJ({request:dG,trackerUrl:aI,success:true,isSendBeacon:true})}return dK}function dm(dD,dE,dC){if(!M(dC)||null===dC){dC=true}if(m&&bd(dD,dE,dC)){return}setTimeout(function(){if(m&&bd(dD,dE,dC)){return}var dH;try{var dG=W.XMLHttpRequest?new W.XMLHttpRequest():W.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):null;dG.open("POST",aI,true);dG.onreadystatechange=function(){if(this.readyState===4&&!(this.status>=200&&this.status<300)){var dI=m&&bd(dD,dE,dC);if(!dI&&dC){cA(dD,dE)}else{if(typeof dE==="function"){dE({request:dD,trackerUrl:aI,success:false,xhr:this})}}}else{if(this.readyState===4&&(typeof dE==="function")){dE({request:dD,trackerUrl:aI,success:true,xhr:this})
+}}};dG.setRequestHeader("Content-Type",cL);dG.withCredentials=true;dG.send(dD)}catch(dF){dH=m&&bd(dD,dE,dC);if(!dH&&dC){cA(dD,dE)}else{if(typeof dE==="function"){dE({request:dD,trackerUrl:aI,success:false})}}}},50)}function cq(dD){var dC=new Date();var dE=dC.getTime()+dD;if(!r||dE>r){r=dE}}function bh(){bj=true;cN=new Date().getTime()}function dw(){var dC=new Date().getTime();return !cN||(dC-cN)>bc}function aD(){if(dw()){b0()}}function a1(){if(J.visibilityState==="hidden"&&dw()){b0()}else{if(J.visibilityState==="visible"){cN=new Date().getTime()}}}function dz(){if(aS||!bc){return}aS=true;ar(W,"focus",bh);ar(W,"blur",aD);ar(W,"visibilitychange",a1);af++;u.addPlugin("HeartBeat"+af,{unload:function(){if(aS&&dw()){b0()}}})}function cS(dG){var dD=new Date();var dC=dD.getTime();dg=dC;if(cR&&dC<cR){var dE=cR-dC;setTimeout(dG,dE);cq(dE+50);cR+=50;return}if(cR===false){var dF=800;cR=dC+dF}dG()}function aT(){if(aH(c2)){bL=false}else{if(aH(bk)){bL=true}}}function bT(dE){if(!aZ){return dE}var dD,dC="&uadata="+t(W.JSON.stringify(aZ));
if(dE instanceof Array){for(dD=0;dD<dE.length;dD++){dE[dD]+=dC}}else{dE+=dC}return dE}function cB(dC){if(!de||!M(g.userAgentData)||!C(g.userAgentData.getHighEntropyValues)){dC();return}aZ={brands:g.userAgentData.brands,platform:g.userAgentData.platform};g.userAgentData.getHighEntropyValues(["brands","model","platform","platformVersion","uaFullVersion","fullVersionList"]).then(function(dE){var dD;if(dE.fullVersionList){delete dE.brands;delete dE.uaFullVersion}aZ=dE;dC()},function(dD){dC()})}function bO(dD,dC,dE){if(!bu){cj.push(dD);return}aT();if(!bL){c1.push(dD);return}aA=true;if(!c6&&dD){if(cQ&&bL){dD+="&consent=1"}dD=bT(dD);cS(function(){if(dd&&bd(dD,dE,true)){cq(100);return}if(cU(dD)){dm(dD,dE)}else{cA(dD,dE)}cq(dC)})}if(!aS){dz()}}function cv(dC){if(c6){return false}return(dC&&dC.length)}function dl(dC,dG){if(!dG||dG>=dC.length){return[dC]}var dD=0;var dE=dC.length;var dF=[];for(dD;dD<dE;dD+=dG){dF.push(dC.slice(dD,dD+dG))}return dF}function dy(dD,dC){if(!cv(dD)){return}if(!bu){cj.push(dD);
return}if(!bL){c1.push(dD);return}aA=true;cS(function(){var dG=dl(dD,50);var dE=0,dF;for(dE;dE<dG.length;dE++){dF='{"requests":["?'+bT(dG[dE]).join('","?')+'"],"send_image":0}';if(dd&&bd(dF,null,false)){cq(100)}else{dm(dF,null,false)}}cq(dC)})}function aY(dC){return br+dC+"."+cf+"."+bx}function b8(dE,dD,dC){dx(dE,"",-129600000,dD,dC)}function ce(){if(bt){return"0"}if(!M(W.showModalDialog)&&M(g.cookieEnabled)){return g.cookieEnabled?"1":"0"}var dC=br+"testcookie";dx(dC,"1",undefined,by,df,b1,aN);var dD=aH(dC)==="1"?"1":"0";b8(dC);return dD}function bp(){bx=cg((df||da)+(by||"/")).slice(0,4)}function cY(){cB(function(){var dI,dH;bu=true;for(dI=0;dI<cj.length;dI++){dH=typeof cj[dI];if(dH==="string"){bO(cj[dI],bS)}else{if(dH==="object"){dy(cj[dI],bS)}}}cj=[]});if(!de){return{}}if(M(dq.res)){return dq}var dD,dF,dG={pdf:"application/pdf",qt:"video/quicktime",realp:"audio/x-pn-realaudio-plugin",wma:"application/x-mplayer2",fla:"application/x-shockwave-flash",java:"application/x-java-vm",ag:"application/x-silverlight"};
if(!((new RegExp("MSIE")).test(g.userAgent))){if(g.mimeTypes&&g.mimeTypes.length){for(dD in dG){if(Object.prototype.hasOwnProperty.call(dG,dD)){dF=g.mimeTypes[dG[dD]];dq[dD]=(dF&&dF.enabledPlugin)?"1":"0"}}}if(!((new RegExp("Edge[ /](\\d+[\\.\\d]+)")).test(g.userAgent))&&typeof navigator.javaEnabled!=="unknown"&&M(g.javaEnabled)&&g.javaEnabled()){dq.java="1"}if(!M(W.showModalDialog)&&M(g.cookieEnabled)){dq.cookie=g.cookieEnabled?"1":"0"}else{dq.cookie=ce()}}var dE=parseInt(ab.width,10);var dC=parseInt(ab.height,10);dq.res=parseInt(dE,10)+"x"+parseInt(dC,10);return dq}function b6(){var dD=aY("cvar"),dC=aH(dD);if(dC&&dC.length){dC=W.JSON.parse(dC);if(Z(dC)){return dC}}return{}}function cV(){if(aV===false){aV=b6()}}function c7(){var dC=cY();return cg((g.userAgent||"")+(g.platform||"")+W.JSON.stringify(dC)+(new Date()).getTime()+Math.random()).slice(0,16)}function aF(){var dC=cY();return cg((g.userAgent||"")+(g.platform||"")+W.JSON.stringify(dC)).slice(0,6)}function bm(){return Math.floor((new Date()).getTime()/1000)
diff --git a/plugins/Login/tests/Integration/PasswordResetterTest.php b/plugins/Login/tests/Integration/PasswordResetterTest.php
index 2dbb4f24c8..cbac1e1fd0 100644
--- a/plugins/Login/tests/Integration/PasswordResetterTest.php
+++ b/plugins/Login/tests/Integration/PasswordResetterTest.php
@@ -16,10 +16,10 @@ use Piwik\Auth;
use Piwik\Container\StaticContainer;
use Piwik\Option;
use Piwik\Plugin\Manager;
-use Piwik\Plugins\UsersManager\Model;
-use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
use Piwik\Plugins\Login\PasswordResetter;
+use Piwik\Plugins\UsersManager\Model;
use Piwik\Tests\Framework\Fixture;
+use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
/**
* @group PasswordResetterTest
@@ -41,6 +41,7 @@ class PasswordResetterTest extends IntegrationTestCase
public function setUp(): void
{
parent::setUp();
+ Fixture::createWebsite('2010-01-01 05:00:00');
$this->passwordResetter = new PasswordResetter();
$this->capturedToken = null;
@@ -171,7 +172,7 @@ class PasswordResetterTest extends IntegrationTestCase
[
'userLogin' => 'pendingUser',
'email' => 'pending@user.io',
- 'idSite' => 1,
+ 'initialIdSite' => 1,
'expiryInDays' => 7
]
);
diff --git a/plugins/UsersManager/API.php b/plugins/UsersManager/API.php
index 0d301929cb..ed3eaf8890 100644
--- a/plugins/UsersManager/API.php
+++ b/plugins/UsersManager/API.php
@@ -727,8 +727,16 @@ class API extends \Piwik\Plugin\API
$password = Common::unsanitizeInputValue($password);
UsersManager::checkPassword($password);
+
+
$initialIdSite = $initialIdSite === null ? null : intval($initialIdSite);
+ if (!Piwik::hasUserSuperUserAccess()) {
+ if (empty($initialIdSite)) {
+ throw new \Exception(Piwik::translate("UsersManager_AddUserNoInitialAccessError"));
+ }
+ }
+
$this->userRepository->create(
(string) $userLogin,
(string) $email,
@@ -750,7 +758,7 @@ class API extends \Piwik\Plugin\API
/**
* @throws Exception
*/
- public function inviteUser($userLogin, $email, $idSite = null, $expiryInDays = null)
+ public function inviteUser($userLogin, $email, $initialIdSite = null, $expiryInDays = null)
{
Piwik::checkUserHasSomeAdminAccess();
UsersManager::dieIfUsersAdminIsDisabled();
@@ -759,9 +767,14 @@ class API extends \Piwik\Plugin\API
$expiryInDays = Config\GeneralConfig::getConfigValue('default_invite_user_token_expiry_days');
}
- $idSite = $idSite === null ? null : intval($idSite);
+ if (empty($initialIdSite)) {
+ throw new \Exception(Piwik::translate("UsersManager_AddUserNoInitialAccessError"));
+ } else {
+ // check if the site exists
+ new Site($initialIdSite);
+ }
- $this->userRepository->inviteUser((string) $userLogin, (string) $email, $idSite, (int) $expiryInDays);
+ $this->userRepository->inviteUser((string) $userLogin, (string) $email, intval($initialIdSite), (int) $expiryInDays);
/**
* Triggered after a new user was invited.
diff --git a/plugins/UsersManager/Repository/UserRepository.php b/plugins/UsersManager/Repository/UserRepository.php
index e806211abc..59f1946813 100644
--- a/plugins/UsersManager/Repository/UserRepository.php
+++ b/plugins/UsersManager/Repository/UserRepository.php
@@ -7,6 +7,7 @@ use Piwik\Container\StaticContainer;
use Piwik\Date;
use Piwik\Metrics\Formatter;
use Piwik\Piwik;
+use Piwik\Plugin;
use Piwik\Plugins\CoreAdminHome\Emails\UserCreatedEmail;
use Piwik\Plugins\UsersManager\API;
use Piwik\Plugins\UsersManager\Emails\UserInviteEmail;
@@ -18,8 +19,6 @@ use Piwik\Plugins\UsersManager\Validators\Email;
use Piwik\Plugins\UsersManager\Validators\Login;
use Piwik\Site;
use Piwik\Validators\BaseValidator;
-use Piwik\Validators\IdSite;
-use Piwik\Plugin;
class UserRepository
{
@@ -60,12 +59,10 @@ class UserRepository
string $password = '',
bool $isPasswordHashed = false
): void {
+
+
if (!Piwik::hasUserSuperUserAccess()) {
- if (empty($initialIdSite)) {
- throw new \Exception(Piwik::translate("UsersManager_AddUserNoInitialAccessError"));
- }
- // check if the site exists
- BaseValidator::check('siteId', $initialIdSite, [new IdSite()]);
+ // check if the user has admin access to the site
Piwik::checkUserHasAdminAccess($initialIdSite);
}
diff --git a/plugins/UsersManager/tests/Integration/APITest.php b/plugins/UsersManager/tests/Integration/APITest.php
index 181553fd23..e7bfb60edf 100644
--- a/plugins/UsersManager/tests/Integration/APITest.php
+++ b/plugins/UsersManager/tests/Integration/APITest.php
@@ -3,14 +3,17 @@
/**
* Matomo - free/libre analytics platform
*
- * @link https://matomo.org
+ * @link https://matomo.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\UsersManager\tests\Integration;
+use Piwik\Access\Capability;
+use Piwik\Access\Role\Admin;
use Piwik\Access\Role\View;
use Piwik\Access\Role\Write;
+use Piwik\API\Request;
use Piwik\Auth\Password;
use Piwik\Config;
use Piwik\Date;
@@ -27,8 +30,6 @@ use Piwik\Plugins\UsersManager\UserUpdater;
use Piwik\Tests\Framework\Fixture;
use Piwik\Tests\Framework\Mock\FakeAccess;
use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
-use Piwik\Access\Role\Admin;
-use Piwik\Access\Capability;
class TestCap1 extends Capability
{
@@ -57,7 +58,7 @@ class TestCap1 extends Capability
public function getIncludedInRoles(): array
{
return [
- Admin::ID
+ Admin::ID,
];
}
}
@@ -89,8 +90,8 @@ class TestCap2 extends Capability
public function getIncludedInRoles(): array
{
return [
- Write::ID,
- Admin::ID
+ Write::ID,
+ Admin::ID,
];
}
}
@@ -153,7 +154,7 @@ class APITest extends IntegrationTestCase
{
parent::setUp();
- $this->api = API::getInstance();
+ $this->api = API::getInstance();
$this->model = new Model();
FakeAccess::clearAccess();
@@ -172,10 +173,10 @@ class APITest extends IntegrationTestCase
parent::tearDown();
}
- public function test_setUserAccess_ShouldTriggerRemoveSiteAccessEvent_IfAccessToAWebsiteIsRemoved()
+ public function testSetUserAccessShouldTriggerRemoveSiteAccessEventIfAccessToAWebsiteIsRemoved()
{
$eventTriggered = false;
- $self = $this;
+ $self = $this;
Piwik::addAction('UsersManager.removeSiteAccess', function ($login, $idSites) use (&$eventTriggered, $self) {
$eventTriggered = true;
$self->assertEquals($self->login, $login);
@@ -187,7 +188,7 @@ class APITest extends IntegrationTestCase
$this->assertTrue($eventTriggered, 'UsersManager.removeSiteAccess event was not triggered');
}
- public function test_setUserAccess_ShouldNotTriggerRemoveSiteAccessEvent_IfAccessIsAdded()
+ public function testSetUserAccessShouldNotTriggerRemoveSiteAccessEventIfAccessIsAdded()
{
$eventTriggered = false;
Piwik::addAction('UsersManager.removeSiteAccess', function () use (&$eventTriggered) {
@@ -199,25 +200,25 @@ class APITest extends IntegrationTestCase
$this->assertFalse($eventTriggered, 'UsersManager.removeSiteAccess event was triggered but should not');
}
- public function test_getAllUsersPreferences_isEmpty_whenNoPreference()
+ public function testGetAllUsersPreferencesIsEmptyWhenNoPreference()
{
$preferences = $this->api->getAllUsersPreferences(['preferenceName']);
$this->assertEmpty($preferences);
}
- public function test_getAllUsersPreferences_isEmpty_whenNoPreferenceAndMultipleRequested()
+ public function testGetAllUsersPreferencesIsEmptyWhenNoPreferenceAndMultipleRequested()
{
$preferences = $this->api->getAllUsersPreferences(['preferenceName', 'randomDoesNotExist']);
$this->assertEmpty($preferences);
}
- public function test_getUserPreference_ShouldReturnADefaultPreference_IfNoneIsSet()
+ public function testGetUserPreferenceShouldReturnADefaultPreferenceIfNoneIsSet()
{
$siteId = $this->api->getUserPreference(API::PREFERENCE_DEFAULT_REPORT, $this->login);
$this->assertEquals('1', $siteId);
}
- public function test_getUserPreference_ShouldReturnASetreference_IfNoneIsSet()
+ public function testGetUserPreferenceShouldReturnASetreferenceIfNoneIsSet()
{
$this->api->setUserPreference($this->login, API::PREFERENCE_DEFAULT_REPORT, 5);
@@ -225,7 +226,7 @@ class APITest extends IntegrationTestCase
$this->assertEquals('5', $siteId);
}
- public function test_initUserPreferenceWithDefault_ShouldSaveTheDefaultPreference_IfPreferenceIsNotSet()
+ public function testInitUserPreferenceWithDefaultShouldSaveTheDefaultPreferenceIfPreferenceIsNotSet()
{
// make sure there is no value saved so it will use default preference
$siteId = Option::get($this->getPreferenceId(API::PREFERENCE_DEFAULT_REPORT));
@@ -238,7 +239,7 @@ class APITest extends IntegrationTestCase
$this->assertEquals('1', $siteId);
}
- public function test_initUserPreferenceWithDefault_ShouldNotSaveTheDefaultPreference_IfPreferenceIsAlreadySet()
+ public function testInitUserPreferenceWithDefaultShouldNotSaveTheDefaultPreferenceIfPreferenceIsAlreadySet()
{
// set value so there will already be a default
Option::set($this->getPreferenceId(API::PREFERENCE_DEFAULT_REPORT), '999');
@@ -253,7 +254,7 @@ class APITest extends IntegrationTestCase
$this->assertEquals('999', $siteId);
}
- public function test_getAllUsersPreferences_shouldGetMultiplePreferences()
+ public function testGetAllUsersPreferencesShouldGetMultiplePreferences()
{
$user2 = 'userLogin2';
$user3 = 'userLogin3';
@@ -267,24 +268,24 @@ class APITest extends IntegrationTestCase
$this->api->setUserPreference($user3, 'RandomNOTREQUESTED', 'RandomNOTREQUESTED');
$expected = [
- $user2 => [
- API::PREFERENCE_DEFAULT_REPORT => 'valueForUser2'
- ],
- $user3 => [
- API::PREFERENCE_DEFAULT_REPORT => 'valueForUser3',
- API::PREFERENCE_DEFAULT_REPORT_DATE => 'otherPreferenceVALUE',
- ],
+ $user2 => [
+ API::PREFERENCE_DEFAULT_REPORT => 'valueForUser2',
+ ],
+ $user3 => [
+ API::PREFERENCE_DEFAULT_REPORT => 'valueForUser3',
+ API::PREFERENCE_DEFAULT_REPORT_DATE => 'otherPreferenceVALUE',
+ ],
];
- $result = $this->api->getAllUsersPreferences([
- API::PREFERENCE_DEFAULT_REPORT,
- API::PREFERENCE_DEFAULT_REPORT_DATE,
- 'randomDoesNotExist'
- ]);
+ $result = $this->api->getAllUsersPreferences([
+ API::PREFERENCE_DEFAULT_REPORT,
+ API::PREFERENCE_DEFAULT_REPORT_DATE,
+ 'randomDoesNotExist',
+ ]);
$this->assertSame($expected, $result);
}
- public function test_getAllUsersPreferences_whenLoginContainsUnderscore()
+ public function testGetAllUsersPreferencesWhenLoginContainsUnderscore()
{
$user2 = 'user_Login2';
$this->api->addUser($user2, 'password', 'userlogin2@password.de');
@@ -292,16 +293,16 @@ class APITest extends IntegrationTestCase
$this->api->setUserPreference($user2, API::PREFERENCE_DEFAULT_REPORT_DATE, 'RandomNOTREQUESTED');
$expected = [
- $user2 => [
- API::PREFERENCE_DEFAULT_REPORT => 'valueForUser2'
- ],
+ $user2 => [
+ API::PREFERENCE_DEFAULT_REPORT => 'valueForUser2',
+ ],
];
- $result = $this->api->getAllUsersPreferences([API::PREFERENCE_DEFAULT_REPORT, 'randomDoesNotExist']);
+ $result = $this->api->getAllUsersPreferences([API::PREFERENCE_DEFAULT_REPORT, 'randomDoesNotExist']);
$this->assertSame($expected, $result);
}
- public function test_setUserPreference_throws_whenPreferenceNameContainsUnderscore()
+ public function testSetUserPreferenceThrowsWhenPreferenceNameContainsUnderscore()
{
$this->expectException(\Exception::class);
@@ -310,20 +311,20 @@ class APITest extends IntegrationTestCase
$this->api->setUserPreference($user2, 'ohOH_myPreferenceName', 'valueForUser2');
}
- public function test_updateUser()
+ public function testUpdateUser()
{
$capturedMails = [];
Piwik::addAction('Mail.send', function (Mail $mail) use (&$capturedMails) {
$capturedMails[] = $mail;
});
- $identity = FakeAccess::$identity;
+ $identity = FakeAccess::$identity;
FakeAccess::$identity = $this->login; // ensure password will be checked against this user
$this->api->updateUser($this->login, 'newPassword', 'email@example.com', false, $this->password);
FakeAccess::$identity = $identity;
$model = new Model();
- $user = $model->getUser($this->login);
+ $user = $model->getUser($this->login);
$this->assertSame('email@example.com', $user['email']);
@@ -335,21 +336,21 @@ class APITest extends IntegrationTestCase
return $mail->getSubject();
}, $capturedMails);
$this->assertEquals([
- 'UsersManager_EmailChangeNotificationSubject', // sent twice to old email and new
- 'UsersManager_EmailChangeNotificationSubject',
- 'UsersManager_PasswordChangeNotificationSubject',
- ], $subjects);
+ 'UsersManager_EmailChangeNotificationSubject', // sent twice to old email and new
+ 'UsersManager_EmailChangeNotificationSubject',
+ 'UsersManager_PasswordChangeNotificationSubject',
+ ], $subjects);
}
- public function test_updateUser_doesNotSendEmailsIfTurnedOffInConfig()
+ public function testUpdateUserDoesNotSendEmailsIfTurnedOffInConfig()
{
Config::getInstance()->General['enable_update_users_email'] = 0;
- $capturedMails = [];
+ $capturedMails = [];
Piwik::addAction('Mail.send', function (Mail $mail) use (&$capturedMails) {
$capturedMails[] = $mail;
});
- $identity = FakeAccess::$identity;
+ $identity = FakeAccess::$identity;
FakeAccess::$identity = $this->login; // en
$this->api->updateUser($this->login, 'newPassword2', 'email2@example.com', false, $this->password);
FakeAccess::$identity = $identity;
@@ -361,14 +362,14 @@ class APITest extends IntegrationTestCase
}
- public function test_updateUser_doesNotSendEmailIfNoChangeAndDoesNotRequirePassword()
+ public function testUpdateUserDoesNotSendEmailIfNoChangeAndDoesNotRequirePassword()
{
$capturedMails = [];
Piwik::addAction('Mail.send', function (Mail $mail) use (&$capturedMails) {
$capturedMails[] = $mail;
});
- $identity = FakeAccess::$identity;
+ $identity = FakeAccess::$identity;
FakeAccess::$identity = $this->login; // en
$this->api->updateUser($this->login, false, strtoupper($this->email));
FakeAccess::$identity = $identity;
@@ -376,12 +377,12 @@ class APITest extends IntegrationTestCase
$this->assertEquals([], $capturedMails);
}
- public function test_updateUser_doesNotChangePasswordIfFalsey()
+ public function testUpdateUserDoesNotChangePasswordIfFalsey()
{
- $model = new Model();
+ $model = new Model();
$userBefore = $model->getUser($this->login);
- $identity = FakeAccess::$identity;
+ $identity = FakeAccess::$identity;
FakeAccess::$identity = $this->login; // ensure password will be checked against this user
$this->api->updateUser($this->login, false, 'email@example.com', false, $this->password);
FakeAccess::$identity = $identity;
@@ -392,7 +393,7 @@ class APITest extends IntegrationTestCase
$this->assertSame($userBefore['ts_password_modified'], $user['ts_password_modified']);
}
- public function test_updateUser_failsIfPasswordTooLong()
+ public function testUpdateUserFailsIfPasswordTooLong()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('UsersManager_ExceptionInvalidPasswordTooLong');
@@ -406,7 +407,7 @@ class APITest extends IntegrationTestCase
);
}
- public function test_update_user_fails_if_email_exists_as_other_user_username()
+ public function testUpdateUserFailsIfEmailExistsAsOtherUserUsername()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('UsersManager_ExceptionEmailExistsAsLogin');
@@ -417,9 +418,9 @@ class APITest extends IntegrationTestCase
$this->api->updateUser($this->login, $this->password, $user2, false, $this->password);
}
- public function test_update_can_update_user_email_to_own_username()
+ public function testUpdateCanUpdateUserEmailToOwnUsername()
{
- $user2 = 'ownemail@example.com';
+ $user2 = 'ownemail@example.com';
$password = 'password';
$this->api->addUser($user2, $password, 'ownemail_wrong@example.com');
@@ -430,7 +431,7 @@ class APITest extends IntegrationTestCase
$this->assertEquals($user2Array['email'], $user2);
}
- public function test_cannot_create_user_if_email_exists_as_username()
+ public function testCannotCreateUserIfEmailExistsAsUsername()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('UsersManager_ExceptionEmailExistsAsLogin');
@@ -441,7 +442,7 @@ class APITest extends IntegrationTestCase
$this->api->addUser('user3', 'password', $user2);
}
- public function test_cannot_create_user_if_username_exists_as_email()
+ public function testCannotCreateUserIfUsernameExistsAsEmail()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('UsersManager_ExceptionLoginExistsAsEmail');
@@ -449,7 +450,7 @@ class APITest extends IntegrationTestCase
$this->api->addUser($this->email, 'password', 'new_user@example.com');
}
- public function test_getSitesAccessFromUser_forSuperUser()
+ public function testGetSitesAccessFromUserForSuperUser()
{
$user2 = 'userLogin2';
$this->api->addUser($user2, 'password', 'userlogin2@password.de');
@@ -462,25 +463,25 @@ class APITest extends IntegrationTestCase
$userUpdater->setSuperUserAccessWithoutCurrentPassword($user2, true);
// super user has admin access for every site
- $access = $this->api->getSitesAccessFromUser($user2);
+ $access = $this->api->getSitesAccessFromUser($user2);
$expected = [
- [
- 'site' => 1,
- 'access' => 'admin'
- ],
- [
- 'site' => 2,
- 'access' => 'admin'
- ],
- [
- 'site' => 3,
- 'access' => 'admin'
- ],
+ [
+ 'site' => 1,
+ 'access' => 'admin',
+ ],
+ [
+ 'site' => 2,
+ 'access' => 'admin',
+ ],
+ [
+ 'site' => 3,
+ 'access' => 'admin',
+ ],
];
$this->assertEquals($expected, $access);
}
- public function test_getUsersPlusRole_shouldReturnSelfIfUserDoesNotHaveAdminAccessToSite()
+ public function testGetUsersPlusRoleShouldReturnSelfIfUserDoesNotHaveAdminAccessToSite()
{
$this->addUserWithAccess('userLogin2', 'view', 1);
$this->setCurrentUser('userLogin2', 'view', 1);
@@ -488,18 +489,18 @@ class APITest extends IntegrationTestCase
$users = $this->api->getUsersPlusRole(1);
$this->cleanUsers($users);
$expected = [
- [
- 'login' => 'userLogin2',
- 'role' => 'view',
- 'capabilities' => [],
- 'email' => 'userLogin2@password.de',
- 'superuser_access' => '0',
- ],
+ [
+ 'login' => 'userLogin2',
+ 'role' => 'view',
+ 'capabilities' => [],
+ 'email' => 'userLogin2@password.de',
+ 'superuser_access' => '0',
+ ],
];
$this->assertEquals($expected, $users);
}
- public function test_getUsersPlusRole_shouldIgnoreOffsetIfLimitIsNotSupplied()
+ public function testGetUsersPlusRoleShouldIgnoreOffsetIfLimitIsNotSupplied()
{
$this->addUserWithAccess('userLogin2', 'view', 1);
$this->setCurrentUser('userLogin2', 'view', 1);
@@ -507,18 +508,18 @@ class APITest extends IntegrationTestCase
$users = $this->api->getUsersPlusRole(1, $limit = null, $offset = 1);
$this->cleanUsers($users);
$expected = [
- [
- 'login' => 'userLogin2',
- 'role' => 'view',
- 'capabilities' => [],
- 'email' => 'userLogin2@password.de',
- 'superuser_access' => '0',
- ],
+ [
+ 'login' => 'userLogin2',
+ 'role' => 'view',
+ 'capabilities' => [],
+ 'email' => 'userLogin2@password.de',
+ 'superuser_access' => '0',
+ ],
];
$this->assertEquals($expected, $users);
}
- public function test_getUsersPlusRole_shouldNotAllowSuperuserFilter_ifUserIsNotSuperUser()
+ public function testGetUsersPlusRoleShouldNotAllowSuperuserFilterIfUserIsNotSuperUser()
{
$this->addUserWithAccess('userLogin2', 'view', 1);
$this->addUserWithAccess('userLogin3', 'superuser', 1);
@@ -527,18 +528,18 @@ class APITest extends IntegrationTestCase
$users = $this->api->getUsersPlusRole(1, null, null, null, 'superuser');
$this->cleanUsers($users);
$expected = [
- [
- 'login' => 'userLogin2',
- 'role' => 'view',
- 'capabilities' => [],
- 'email' => 'userLogin2@password.de',
- 'superuser_access' => '0',
- ],
+ [
+ 'login' => 'userLogin2',
+ 'role' => 'view',
+ 'capabilities' => [],
+ 'email' => 'userLogin2@password.de',
+ 'superuser_access' => '0',
+ ],
];
$this->assertEquals($expected, $users);
}
- public function test_getUsersPlusRole_shouldReturnAllUsersAndAccess_ifUserHasAdminAccess()
+ public function testGetUsersPlusRoleShouldReturnAllUsersAndAccessIfUserHasAdminAccess()
{
$this->addUserWithAccess('userLogin2', 'admin', 1);
$this->addUserWithAccess('userLogin3', 'view', 1);
@@ -549,30 +550,30 @@ class APITest extends IntegrationTestCase
$users = $this->api->getUsersPlusRole(1);
$this->cleanUsers($users);
$expected = [
- [
- 'login' => 'userLogin2',
- 'role' => 'admin',
- 'capabilities' => [],
- 'email' => 'userLogin2@password.de',
- 'superuser_access' => false,
- ],
- [
- 'login' => 'userLogin3',
- 'role' => 'view',
- 'capabilities' => [],
- 'superuser_access' => false,
- ],
- [
- 'login' => 'userLogin4',
- 'role' => 'admin',
- 'capabilities' => [],
- 'superuser_access' => false,
- ],
+ [
+ 'login' => 'userLogin2',
+ 'role' => 'admin',
+ 'capabilities' => [],
+ 'email' => 'userLogin2@password.de',
+ 'superuser_access' => false,
+ ],
+ [
+ 'login' => 'userLogin3',
+ 'role' => 'view',
+ 'capabilities' => [],
+ 'superuser_access' => false,
+ ],
+ [
+ 'login' => 'userLogin4',
+ 'role' => 'admin',
+ 'capabilities' => [],
+ 'superuser_access' => false,
+ ],
];
$this->assertEquals($expected, $users);
}
- public function test_getUsersPlusRole_shouldLimitUsersReturnedToThoseWithAccessToSitesAsCurrentUsersAdminSites_IfCurrentUserIsAdmin()
+ public function testGetUsersPlusRoleForAdminShouldLimitUsersToThoseWithAccessToSitesAsCurrentUsersAdminSites()
{
$this->addUserWithAccess('userLogin2', 'admin', [1, 2]);
$this->addUserWithAccess('userLogin3', 'view', 1);
@@ -584,36 +585,36 @@ class APITest extends IntegrationTestCase
$users = $this->api->getUsersPlusRole(1);
$this->cleanUsers($users);
$expected = [
- [
- 'login' => 'userLogin2',
- 'role' => 'admin',
- 'capabilities' => [],
- 'email' => 'userLogin2@password.de',
- 'superuser_access' => false,
- ],
- [
- 'login' => 'userLogin3',
- 'role' => 'view',
- 'capabilities' => [],
- 'superuser_access' => false,
- ],
- [
- 'login' => 'userLogin4',
- 'role' => 'admin',
- 'capabilities' => [],
- 'superuser_access' => false,
- ],
- [
- 'login' => 'userLogin5',
- 'role' => 'noaccess',
- 'capabilities' => [],
- 'superuser_access' => false,
- ],
+ [
+ 'login' => 'userLogin2',
+ 'role' => 'admin',
+ 'capabilities' => [],
+ 'email' => 'userLogin2@password.de',
+ 'superuser_access' => false,
+ ],
+ [
+ 'login' => 'userLogin3',
+ 'role' => 'view',
+ 'capabilities' => [],
+ 'superuser_access' => false,
+ ],
+ [
+ 'login' => 'userLogin4',
+ 'role' => 'admin',
+ 'capabilities' => [],
+ 'superuser_access' => false,
+ ],
+ [
+ 'login' => 'userLogin5',
+ 'role' => 'noaccess',
+ 'capabilities' => [],
+ 'superuser_access' => false,
+ ],
];
$this->assertEquals($expected, $users);
}
- public function test_getUsersPlusRole_shouldReturnAllUsersAndAccess_ifUserHasSuperuserAccess()
+ public function testGetUsersPlusRoleShouldReturnAllUsersAndAccessIfUserHasSuperuserAccess()
{
$this->addUserWithAccess('userLogin2', 'superuser', 1);
$this->addUserWithAccess('userLogin3', 'view', 1);
@@ -624,51 +625,51 @@ class APITest extends IntegrationTestCase
$users = $this->api->getUsersPlusRole(1);
$this->cleanUsers($users);
$expected = [
- [
- 'login' => 'userLogin',
- 'email' => 'userlogin@password.de',
- 'superuser_access' => false,
- 'role' => 'noaccess',
- 'capabilities' => [],
- 'uses_2fa' => false,
- ],
- [
- 'login' => 'userLogin2',
- 'email' => 'userLogin2@password.de',
- 'superuser_access' => true,
- 'role' => 'superuser',
- 'capabilities' => [],
- 'uses_2fa' => false,
- ],
- [
- 'login' => 'userLogin3',
- 'email' => 'userLogin3@password.de',
- 'superuser_access' => false,
- 'role' => 'view',
- 'capabilities' => [],
- 'uses_2fa' => false,
- ],
- [
- 'login' => 'userLogin4',
- 'email' => 'userLogin4@password.de',
- 'superuser_access' => true,
- 'role' => 'superuser',
- 'capabilities' => [],
- 'uses_2fa' => false,
- ],
- [
- 'login' => 'userLogin5',
- 'email' => 'userLogin5@password.de',
- 'superuser_access' => false,
- 'role' => 'noaccess',
- 'capabilities' => [],
- 'uses_2fa' => false,
- ],
+ [
+ 'login' => 'userLogin',
+ 'email' => 'userlogin@password.de',
+ 'superuser_access' => false,
+ 'role' => 'noaccess',
+ 'capabilities' => [],
+ 'uses_2fa' => false,
+ ],
+ [
+ 'login' => 'userLogin2',
+ 'email' => 'userLogin2@password.de',
+ 'superuser_access' => true,
+ 'role' => 'superuser',
+ 'capabilities' => [],
+ 'uses_2fa' => false,
+ ],
+ [
+ 'login' => 'userLogin3',
+ 'email' => 'userLogin3@password.de',
+ 'superuser_access' => false,
+ 'role' => 'view',
+ 'capabilities' => [],
+ 'uses_2fa' => false,
+ ],
+ [
+ 'login' => 'userLogin4',
+ 'email' => 'userLogin4@password.de',
+ 'superuser_access' => true,
+ 'role' => 'superuser',
+ 'capabilities' => [],
+ 'uses_2fa' => false,
+ ],
+ [
+ 'login' => 'userLogin5',
+ 'email' => 'userLogin5@password.de',
+ 'superuser_access' => false,
+ 'role' => 'noaccess',
+ 'capabilities' => [],
+ 'uses_2fa' => false,
+ ],
];
$this->assertEquals($expected, $users);
}
- public function test_getUsersPlusRole_shouldFilterUsersByAccessCorrectly()
+ public function testGetUsersPlusRoleShouldFilterUsersByAccessCorrectly()
{
$this->addUserWithAccess('userLogin2', 'admin', 1);
$this->addUserWithAccess('userLogin3', 'view', 1);
@@ -680,18 +681,19 @@ class APITest extends IntegrationTestCase
$users = $this->api->getUsersPlusRole(1, null, null, null, 'admin');
$this->cleanUsers($users);
$expected = [
- [
- 'login' => 'userLogin2',
- 'role' => 'admin',
- 'capabilities' => [],
- 'email' => 'userLogin2@password.de',
- 'superuser_access' => false,
- ],
- ['login' => 'userLogin5',
- 'role' => 'admin',
- 'capabilities' => [],
- 'superuser_access' => false,
- ],
+ [
+ 'login' => 'userLogin2',
+ 'role' => 'admin',
+ 'capabilities' => [],
+ 'email' => 'userLogin2@password.de',
+ 'superuser_access' => false,
+ ],
+ [
+ 'login' => 'userLogin5',
+ 'role' => 'admin',
+ 'capabilities' => [],
+ 'superuser_access' => false,
+ ],
];
$this->assertEquals($expected, $users);
@@ -699,12 +701,12 @@ class APITest extends IntegrationTestCase
$users = $this->api->getUsersPlusRole(1, null, null, null, 'write');
$this->cleanUsers($users);
$expected = [
- ['login' => 'userLogin6', 'role' => 'write', 'capabilities' => [], 'superuser_access' => false],
+ ['login' => 'userLogin6', 'role' => 'write', 'capabilities' => [], 'superuser_access' => false],
];
$this->assertEquals($expected, $users);
}
- public function test_getUsersPlusRole_shouldReturnUsersWithNoAccessCorrectly()
+ public function testGetUsersPlusRoleShouldReturnUsersWithNoAccessCorrectly()
{
$this->addUserWithAccess('userLogin2', 'noaccess', 1);
$this->addUserWithAccess('userLogin3', 'view', 1);
@@ -714,35 +716,35 @@ class APITest extends IntegrationTestCase
$users = $this->api->getUsersPlusRole(1, null, null, null, 'noaccess');
$this->cleanUsers($users);
$expected = [
- [
- 'login' => 'userLogin',
- 'role' => 'noaccess',
- 'superuser_access' => false,
- 'email' => 'userlogin@password.de',
- 'capabilities' => [],
- 'uses_2fa' => false,
- ],
- [
- 'login' => 'userLogin2',
- 'role' => 'noaccess',
- 'superuser_access' => false,
- 'email' => 'userLogin2@password.de',
- 'capabilities' => [],
- 'uses_2fa' => false,
- ],
- [
- 'login' => 'userLogin5',
- 'role' => 'noaccess',
- 'superuser_access' => false,
- 'email' => 'userLogin5@password.de',
- 'capabilities' => [],
- 'uses_2fa' => false,
- ],
+ [
+ 'login' => 'userLogin',
+ 'role' => 'noaccess',
+ 'superuser_access' => false,
+ 'email' => 'userlogin@password.de',
+ 'capabilities' => [],
+ 'uses_2fa' => false,
+ ],
+ [
+ 'login' => 'userLogin2',
+ 'role' => 'noaccess',
+ 'superuser_access' => false,
+ 'email' => 'userLogin2@password.de',
+ 'capabilities' => [],
+ 'uses_2fa' => false,
+ ],
+ [
+ 'login' => 'userLogin5',
+ 'role' => 'noaccess',
+ 'superuser_access' => false,
+ 'email' => 'userLogin5@password.de',
+ 'capabilities' => [],
+ 'uses_2fa' => false,
+ ],
];
$this->assertEquals($expected, $users);
}
- public function test_getUsersPlusRole_shouldSearchForSuperUsersCorrectly()
+ public function testGetUsersPlusRoleShouldSearchForSuperUsersCorrectly()
{
$this->addUserWithAccess('userLogin2', 'admin', 1);
$userUpdater = new UserUpdater();
@@ -755,27 +757,27 @@ class APITest extends IntegrationTestCase
$users = $this->api->getUsersPlusRole(1, null, null, null, 'superuser');
$this->cleanUsers($users);
$expected = [
- [
- 'login' => 'userLogin2',
- 'email' => 'userLogin2@password.de',
- 'superuser_access' => true,
- 'role' => 'superuser',
- 'capabilities' => [],
- 'uses_2fa' => false,
- ],
- [
- 'login' => 'userLogin4',
- 'email' => 'userLogin4@password.de',
- 'superuser_access' => true,
- 'role' => 'superuser',
- 'capabilities' => [],
- 'uses_2fa' => false,
- ],
+ [
+ 'login' => 'userLogin2',
+ 'email' => 'userLogin2@password.de',
+ 'superuser_access' => true,
+ 'role' => 'superuser',
+ 'capabilities' => [],
+ 'uses_2fa' => false,
+ ],
+ [
+ 'login' => 'userLogin4',
+ 'email' => 'userLogin4@password.de',
+ 'superuser_access' => true,
+ 'role' => 'superuser',
+ 'capabilities' => [],
+ 'uses_2fa' => false,
+ ],
];
$this->assertEquals($expected, $users);
}
- public function test_getUsersPlusRole_shouldSearchByTextCorrectly()
+ public function testGetUsersPlusRoleShouldSearchByTextCorrectly()
{
$this->addUserWithAccess('searchTextLogin', 'superuser', 1, 'someemail@email.com');
$this->addUserWithAccess('userLogin2', 'view', 1, 'searchTextdef@email.com');
@@ -786,27 +788,27 @@ class APITest extends IntegrationTestCase
$users = $this->api->getUsersPlusRole(1, null, null, 'searchText');
$this->cleanUsers($users);
$expected = [
- [
- 'login' => 'searchTextLogin',
- 'email' => 'someemail@email.com',
- 'superuser_access' => true,
- 'role' => 'superuser',
- 'capabilities' => [],
- 'uses_2fa' => false,
- ],
- [
- 'login' => 'userLogin2',
- 'email' => 'searchTextdef@email.com',
- 'superuser_access' => false,
- 'role' => 'view',
- 'capabilities' => [],
- 'uses_2fa' => false,
- ],
+ [
+ 'login' => 'searchTextLogin',
+ 'email' => 'someemail@email.com',
+ 'superuser_access' => true,
+ 'role' => 'superuser',
+ 'capabilities' => [],
+ 'uses_2fa' => false,
+ ],
+ [
+ 'login' => 'userLogin2',
+ 'email' => 'searchTextdef@email.com',
+ 'superuser_access' => false,
+ 'role' => 'view',
+ 'capabilities' => [],
+ 'uses_2fa' => false,
+ ],
];
$this->assertEquals($expected, $users);
}
- public function test_getUsersPlusRole_shouldApplyLimitAndOffsetCorrectly()
+ public function testGetUsersPlusRoleShouldApplyLimitAndOffsetCorrectly()
{
$this->addUserWithAccess('searchTextLogin', 'superuser', 1, 'someemail@email.com');
$this->addUserWithAccess('userLogin2', 'view', 1, 'searchTextdef@email.com');
@@ -817,70 +819,71 @@ class APITest extends IntegrationTestCase
$users = $this->api->getUsersPlusRole(1, $limit = 2, $offset = 1);
$this->cleanUsers($users);
$expected = [
- [
- 'login' => 'userLogin',
- 'email' => 'userlogin@password.de',
- 'superuser_access' => false,
- 'role' => 'noaccess',
- 'capabilities' => [],
- 'uses_2fa' => false,
- ],
- [
- 'login' => 'userLogin2',
- 'email' => 'searchTextdef@email.com',
- 'superuser_access' => false,
- 'role' => 'view',
- 'capabilities' => [],
- 'uses_2fa' => false,
- ],
+ [
+ 'login' => 'userLogin',
+ 'email' => 'userlogin@password.de',
+ 'superuser_access' => false,
+ 'role' => 'noaccess',
+ 'capabilities' => [],
+ 'uses_2fa' => false,
+ ],
+ [
+ 'login' => 'userLogin2',
+ 'email' => 'searchTextdef@email.com',
+ 'superuser_access' => false,
+ 'role' => 'view',
+ 'capabilities' => [],
+ 'uses_2fa' => false,
+ ],
];
$this->assertEquals($expected, $users);
}
- public function test_getSitesAccessForUser_shouldReturnAccessForUser()
+ public function testGetSitesAccessForUserShouldReturnAccessForUser()
{
$this->api->setUserAccess('userLogin', 'admin', [1]);
$this->api->setUserAccess('userLogin', 'view', [2]);
$this->api->setUserAccess('userLogin', 'view', [3]);
- $access = $this->api->getSitesAccessForUser('userLogin');
+ $access = $this->api->getSitesAccessForUser('userLogin');
$expected = [
- ['idsite' => '1', 'site_name' => 'Piwik test', 'role' => 'admin', 'capabilities' => []],
- ['idsite' => '2', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
- ['idsite' => '3', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
+ ['idsite' => '1', 'site_name' => 'Piwik test', 'role' => 'admin', 'capabilities' => []],
+ ['idsite' => '2', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
+ ['idsite' => '3', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
];
$this->assertEquals($expected, $access);
}
- public function getSitesAccessForUser_shouldIgnoreOffsetIfLimitNotSupplied()
+ public function testGetSitesAccessForUserShouldIgnoreOffsetIfLimitNotSupplied()
{
$this->api->setUserAccess('userLogin', 'admin', [1]);
$this->api->setUserAccess('userLogin', 'view', [2]);
$this->api->setUserAccess('userLogin', 'view', [3]);
- $access = $this->api->getSitesAccessForUser('userLogin', $limit = null, $offset = 1);
+ $access = $this->api->getSitesAccessForUser('userLogin', $limit = null, $offset = 1);
$expected = [
- ['idsite' => '2', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
- ['idsite' => '3', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
+ ['idsite' => '1', 'site_name' => 'Piwik test', 'role' => 'admin', 'capabilities' => []],
+ ['idsite' => '2', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
+ ['idsite' => '3', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
];
$this->assertEquals($expected, $access);
}
- public function test_getSitesAccessForUser_shouldApplyLimitAndOffsetCorrectly()
+ public function testGetSitesAccessForUserShouldApplyLimitAndOffsetCorrectly()
{
$this->api->setUserAccess('userLogin', 'admin', [1]);
$this->api->setUserAccess('userLogin', 'view', [2]);
$this->api->setUserAccess('userLogin', 'view', [3]);
- $access = $this->api->getSitesAccessForUser('userLogin', $limit = 2, $offset = 1);
+ $access = $this->api->getSitesAccessForUser('userLogin', $limit = 2, $offset = 1);
$expected = [
- ['idsite' => '2', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
- ['idsite' => '3', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
+ ['idsite' => '2', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
+ ['idsite' => '3', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
];
$this->assertEquals($expected, $access);
}
- public function test_getSitesAccessForUser_shouldSearchSitesCorrectly()
+ public function testGetSitesAccessForUserShouldSearchSitesCorrectly()
{
Fixture::createWebsite('2010-01-02 00:00:00');
@@ -906,30 +909,30 @@ class APITest extends IntegrationTestCase
'the searchTerm group'
);
- $access = $this->api->getSitesAccessForUser('userLogin', null, null, 'searchTerm');
+ $access = $this->api->getSitesAccessForUser('userLogin', null, null, 'searchTerm');
$expected = [
- ['idsite' => '2', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
- ['idsite' => '3', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
- ['idsite' => '1', 'site_name' => 'searchTerm site', 'role' => 'admin', 'capabilities' => []],
+ ['idsite' => '2', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
+ ['idsite' => '3', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
+ ['idsite' => '1', 'site_name' => 'searchTerm site', 'role' => 'admin', 'capabilities' => []],
];
$this->assertEquals($expected, $access);
}
- public function test_getSitesAccessForUser_shouldFilterByAccessCorrectly()
+ public function testGetSitesAccessForUserShouldFilterByAccessCorrectly()
{
$this->api->setUserAccess('userLogin', 'admin', [1]);
$this->api->setUserAccess('userLogin', 'view', [2]);
$this->api->setUserAccess('userLogin', 'view', [3]);
- $access = $this->api->getSitesAccessForUser('userLogin', null, null, null, 'view');
+ $access = $this->api->getSitesAccessForUser('userLogin', null, null, null, 'view');
$expected = [
- ['idsite' => '2', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
- ['idsite' => '3', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
+ ['idsite' => '2', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
+ ['idsite' => '3', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
];
$this->assertEquals($expected, $access);
}
- public function test_getSitesAccessForUser_shouldLimitSitesIfUserIsAdmin()
+ public function testGetSitesAccessForUserShouldLimitSitesIfUserIsAdmin()
{
$this->addUserWithAccess('userLogin2', 'view', [1, 2, 3], 'userlogin2@email.com');
@@ -938,15 +941,15 @@ class APITest extends IntegrationTestCase
$this->setCurrentUser('userLogin', 'admin', [1, 2]);
- $access = $this->api->getSitesAccessForUser('userLogin2', null, null, null, 'view');
+ $access = $this->api->getSitesAccessForUser('userLogin2', null, null, null, 'view');
$expected = [
- ['idsite' => '1', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
- ['idsite' => '2', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
+ ['idsite' => '1', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
+ ['idsite' => '2', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
];
$this->assertEquals($expected, $access);
}
- public function test_getSitesAccessForUser_shouldLimitSitesIfUserIsAdmin_AndStillSelectNoAccessSitesCorrectly()
+ public function testGetSitesAccessForUserShouldLimitSitesIfUserIsAdminAndStillSelectNoAccessSitesCorrectly()
{
$this->addUserWithAccess('userLogin2', 'view', [1], 'userlogin2@email.com');
@@ -954,46 +957,46 @@ class APITest extends IntegrationTestCase
$this->setCurrentUser('userLogin', 'admin', [1, 2, 3]);
- $access = $this->api->getSitesAccessForUser('userLogin2', null, null, null, 'noaccess');
+ $access = $this->api->getSitesAccessForUser('userLogin2', null, null, null, 'noaccess');
$expected = [
- ['idsite' => '2', 'site_name' => 'Piwik test', 'role' => 'noaccess', 'capabilities' => []],
- ['idsite' => '3', 'site_name' => 'Piwik test', 'role' => 'noaccess', 'capabilities' => []],
+ ['idsite' => '2', 'site_name' => 'Piwik test', 'role' => 'noaccess', 'capabilities' => []],
+ ['idsite' => '3', 'site_name' => 'Piwik test', 'role' => 'noaccess', 'capabilities' => []],
];
$this->assertEquals($expected, $access);
}
- public function test_getSitesAccessForUser_shouldSelectSitesCorrectlyIfAtLeastViewRequested()
+ public function testGetSitesAccessForUserShouldSelectSitesCorrectlyIfAtLeastViewRequested()
{
$this->addUserWithAccess('userLogin2', 'view', [1], 'userlogin2@email.com');
$this->api->setUserAccess('userLogin2', 'admin', [2]);
- $access = $this->api->getSitesAccessForUser('userLogin2', null, null, null, 'some');
+ $access = $this->api->getSitesAccessForUser('userLogin2', null, null, null, 'some');
$expected = [
- ['idsite' => '1', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
- ['idsite' => '2', 'site_name' => 'Piwik test', 'role' => 'admin', 'capabilities' => []],
+ ['idsite' => '1', 'site_name' => 'Piwik test', 'role' => 'view', 'capabilities' => []],
+ ['idsite' => '2', 'site_name' => 'Piwik test', 'role' => 'admin', 'capabilities' => []],
];
$this->assertEquals($expected, $access);
}
- public function test_getSitesAccessForUser_shouldReportIfUserHasNoAccessToSites()
+ public function testGetSitesAccessForUserShouldReportIfUserHasNoAccessToSites()
{
- $access = $this->api->getSitesAccessForUser('userLogin');
+ $access = $this->api->getSitesAccessForUser('userLogin');
$expected = [
- ['idsite' => '1', 'site_name' => 'Piwik test', 'role' => 'noaccess', 'capabilities' => []],
- ['idsite' => '2', 'site_name' => 'Piwik test', 'role' => 'noaccess', 'capabilities' => []],
- ['idsite' => '3', 'site_name' => 'Piwik test', 'role' => 'noaccess', 'capabilities' => []],
+ ['idsite' => '1', 'site_name' => 'Piwik test', 'role' => 'noaccess', 'capabilities' => []],
+ ['idsite' => '2', 'site_name' => 'Piwik test', 'role' => 'noaccess', 'capabilities' => []],
+ ['idsite' => '3', 'site_name' => 'Piwik test', 'role' => 'noaccess', 'capabilities' => []],
];
$this->assertEquals($expected, $access);
// test when search returns empty result
$this->api->setUserAccess('userLogin', 'view', 1);
- $access = $this->api->getSitesAccessForUser('userLogin', null, null, 'asdklfjds');
+ $access = $this->api->getSitesAccessForUser('userLogin', null, null, 'asdklfjds');
$expected = [];
$this->assertEquals($expected, $access);
}
- public function test_setUserAccess_MultipleRolesCannotBeSet()
+ public function testSetUserAccessMultipleRolesCannotBeSet()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('UsersManager_ExceptionMultipleRoleSet');
@@ -1001,7 +1004,7 @@ class APITest extends IntegrationTestCase
$this->api->setUserAccess($this->login, ['view', 'admin'], [1]);
}
- public function test_setUserAccess_NeedsAtLeastOneRole()
+ public function testSetUserAccessNeedsAtLeastOneRole()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('UsersManager_ExceptionNoRoleSet');
@@ -1009,7 +1012,7 @@ class APITest extends IntegrationTestCase
$this->api->setUserAccess($this->login, [TestCap2::ID], [1]);
}
- public function test_setUserAccess_NeedsAtLeastOneRoleAsString()
+ public function testSetUserAccessNeedsAtLeastOneRoleAsString()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('UsersManager_ExceptionAccessValues');
@@ -1017,7 +1020,7 @@ class APITest extends IntegrationTestCase
$this->api->setUserAccess($this->login, TestCap2::ID, [1]);
}
- public function test_setUserAccess_InvalidCapability()
+ public function testSetUserAccessInvalidCapability()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('UsersManager_ExceptionAccessValues');
@@ -1025,7 +1028,7 @@ class APITest extends IntegrationTestCase
$this->api->setUserAccess($this->login, ['admin', 'foobar'], [1]);
}
- public function test_setUserAccess_NeedsAtLeastOneRoleNoneGiven()
+ public function testSetUserAccessNeedsAtLeastOneRoleNoneGiven()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('UsersManager_ExceptionNoRoleSet');
@@ -1033,7 +1036,7 @@ class APITest extends IntegrationTestCase
$this->api->setUserAccess($this->login, [], [1]);
}
- public function test_setUserAccess_CannotSetAdminToAnonymous()
+ public function testSetUserAccessCannotSetAdminToAnonymous()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('UsersManager_ExceptionAnonymousAccessNotPossible');
@@ -1041,7 +1044,7 @@ class APITest extends IntegrationTestCase
$this->api->setUserAccess('anonymous', 'admin', [1]);
}
- public function test_setUserAccess_CannotSetWriteToAnonymous()
+ public function testSetUserAccessCannotSetWriteToAnonymous()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('UsersManager_ExceptionAnonymousAccessNotPossible');
@@ -1049,7 +1052,7 @@ class APITest extends IntegrationTestCase
$this->api->setUserAccess('anonymous', 'write', [1]);
}
- public function test_setUserAccess_UserDoesNotExist()
+ public function testSetUserAccessUserDoesNotExist()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('UsersManager_ExceptionUserDoesNotExist');
@@ -1057,7 +1060,7 @@ class APITest extends IntegrationTestCase
$this->api->setUserAccess('foobar', Admin::ID, [1]);
}
- public function test_setUserAccess_SetRoleAndCapabilities()
+ public function testSetUserAccessSetRoleAndCapabilities()
{
$access = [TestCap2::ID, View::ID, TestCap3::ID];
$this->api->setUserAccess($this->login, $access, [1]);
@@ -1065,14 +1068,14 @@ class APITest extends IntegrationTestCase
$access = $this->model->getSitesAccessFromUser($this->login);
$expected = [
- ['site' => '1', 'access' => 'view'],
- ['site' => '1', 'access' => TestCap2::ID],
- ['site' => '1', 'access' => TestCap3::ID],
+ ['site' => '1', 'access' => 'view'],
+ ['site' => '1', 'access' => TestCap2::ID],
+ ['site' => '1', 'access' => TestCap3::ID],
];
$this->assertEquals($expected, $access);
}
- public function test_setUserAccess_SetRoleAsString()
+ public function testSetUserAccessSetRoleAsString()
{
$this->api->setUserAccess($this->login, View::ID, [1]);
@@ -1080,7 +1083,7 @@ class APITest extends IntegrationTestCase
$this->assertEquals([['site' => '1', 'access' => 'view']], $access);
}
- public function test_setUserAccess_SetRoleAsArray()
+ public function testSetUserAccessSetRoleAsArray()
{
$this->api->setUserAccess($this->login, [View::ID], [1]);
@@ -1088,7 +1091,7 @@ class APITest extends IntegrationTestCase
$this->assertEquals([['site' => '1', 'access' => 'view']], $access);
}
- public function test_addCapabilities_failsWhenNotCapabilityIsGivenAsString()
+ public function testAddCapabilitiesFailsWhenNotCapabilityIsGivenAsString()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('UsersManager_ExceptionAccessValues');
@@ -1096,7 +1099,7 @@ class APITest extends IntegrationTestCase
$this->api->addCapabilities($this->login, View::ID, [1]);
}
- public function test_addCapabilities_failsWhenNotCapabilityIsGivenAsArray()
+ public function testAddCapabilitiesFailsWhenNotCapabilityIsGivenAsArray()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('UsersManager_ExceptionAccessValues');
@@ -1104,7 +1107,7 @@ class APITest extends IntegrationTestCase
$this->api->addCapabilities($this->login, [TestCap2::ID, View::ID], [1]);
}
- public function test_addCapabilities_failsWhenUserDoesNotExist()
+ public function testAddCapabilitiesFailsWhenUserDoesNotExist()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('UsersManager_ExceptionUserDoesNotExist');
@@ -1112,7 +1115,7 @@ class APITest extends IntegrationTestCase
$this->api->addCapabilities('foobar', [TestCap2::ID], [1]);
}
- public function test_addCapabilities_DoesNotAddSameCapabilityTwice()
+ public function testAddCapabilitiesDoesNotAddSameCapabilityTwice()
{
$addAccess = [TestCap2::ID, View::ID, TestCap3::ID];
$this->api->setUserAccess($this->login, $addAccess, [1]);
@@ -1120,9 +1123,9 @@ class APITest extends IntegrationTestCase
$access = $this->model->getSitesAccessFromUser($this->login);
$expected = [
- ['site' => '1', 'access' => 'view'],
- ['site' => '1', 'access' => TestCap2::ID],
- ['site' => '1', 'access' => TestCap3::ID],
+ ['site' => '1', 'access' => 'view'],
+ ['site' => '1', 'access' => TestCap2::ID],
+ ['site' => '1', 'access' => TestCap3::ID],
];
$this->assertEquals($expected, $access);
@@ -1134,11 +1137,11 @@ class APITest extends IntegrationTestCase
$this->api->addCapabilities($this->login, [TestCap2::ID, TestCap1::ID, TestCap3::ID], [1]);
$expected[] = ['site' => '1', 'access' => TestCap1::ID];
- $access = $this->model->getSitesAccessFromUser($this->login);
+ $access = $this->model->getSitesAccessFromUser($this->login);
$this->assertEquals($expected, $access);
}
- public function test_addCapabilities_DoesNotAddCapabilityToUserWithNoRole()
+ public function testAddCapabilitiesDoesNotAddCapabilityToUserWithNoRole()
{
self::expectException(\Exception::class);
self::expectExceptionMessage('UsersManager_ExceptionNoCapabilitiesWithoutRole');
@@ -1150,34 +1153,34 @@ class APITest extends IntegrationTestCase
$this->api->addCapabilities($this->login, array(TestCap2::ID, TestCap3::ID), array(1));
}
- public function test_addCapabilities_DoesNotAddCapabilitiesWhichAreIncludedInRoleAlready()
+ public function testAddCapabilitiesDoesNotAddCapabilitiesWhichAreIncludedInRoleAlready()
{
$this->api->setUserAccess($this->login, Write::ID, [1]);
$access = $this->model->getSitesAccessFromUser($this->login);
$expected = [
- ['site' => '1', 'access' => 'write'],
+ ['site' => '1', 'access' => 'write'],
];
$this->assertEquals($expected, $access);
$this->api->addCapabilities($this->login, [TestCap2::ID, TestCap3::ID], [1]);
$expected[] = ['site' => '1', 'access' => TestCap3::ID];
- $access = $this->model->getSitesAccessFromUser($this->login);
+ $access = $this->model->getSitesAccessFromUser($this->login);
// did not add TestCap2
$this->assertEquals($expected, $access);
}
- public function test_addCapabilities_DoesAddCapabilitiesWhichAreNotIncludedInRoleYetAlready()
+ public function testAddCapabilitiesDoesAddCapabilitiesWhichAreNotIncludedInRoleYetAlready()
{
$this->api->setUserAccess($this->login, Admin::ID, [1]);
$access = $this->model->getSitesAccessFromUser($this->login);
$expected = [
- ['site' => '1', 'access' => 'admin'],
+ ['site' => '1', 'access' => 'admin'],
];
$this->assertEquals($expected, $access);
@@ -1187,7 +1190,7 @@ class APITest extends IntegrationTestCase
$this->assertEquals($expected, $access);
}
- public function test_removeCapabilities_failsWhenNotCapabilityIsGivenAsString()
+ public function testRemoveCapabilitiesFailsWhenNotCapabilityIsGivenAsString()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('UsersManager_ExceptionAccessValues');
@@ -1195,7 +1198,7 @@ class APITest extends IntegrationTestCase
$this->api->removeCapabilities($this->login, View::ID, [1]);
}
- public function test_removeCapabilities_failsWhenNotCapabilityIsGivenAsArray()
+ public function testRemoveCapabilitiesFailsWhenNotCapabilityIsGivenAsArray()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('UsersManager_ExceptionAccessValues');
@@ -1203,7 +1206,7 @@ class APITest extends IntegrationTestCase
$this->api->removeCapabilities($this->login, [TestCap2::ID, View::ID], [1]);
}
- public function test_removeCapabilities_failsWhenUserDoesNotExist()
+ public function testRemoveCapabilitiesFailsWhenUserDoesNotExist()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('UsersManager_ExceptionUserDoesNotExist');
@@ -1211,7 +1214,7 @@ class APITest extends IntegrationTestCase
$this->api->removeCapabilities('foobar', [TestCap2::ID], [1]);
}
- public function test_removeCapabilities()
+ public function testRemoveCapabilities()
{
$addAccess = [View::ID, TestCap2::ID, TestCap3::ID, TestCap1::ID];
$this->api->setUserAccess($this->login, $addAccess, [1]);
@@ -1225,7 +1228,7 @@ class APITest extends IntegrationTestCase
$this->assertEquals([View::ID, TestCap1::ID], $access);
}
- public function test_setSuperUserAccess_failsIfCurrentPasswordIsIncorrect()
+ public function testSetSuperUserAccessFailsIfCurrentPasswordIsIncorrect()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('UsersManager_CurrentPasswordNotCorrect');
@@ -1233,15 +1236,49 @@ class APITest extends IntegrationTestCase
$this->api->setSuperUserAccess($this->login, true, 'asldfkjds');
}
+
+ public function testInviteUserInitialIdSiteMissing()
+ {
+ $this->expectException(\Exception::class);
+ $this->expectExceptionMessage('UsersManager_AddUserNoInitialAccessError');
+ Request::processRequest(
+ 'UsersManager.inviteUser',
+ [
+ 'userLogin' => "testInviteUser",
+ 'email' => "testInviteUser@example.com",
+ 'expiryInDays' => 7,
+ ]
+ );
+ }
+
+ public function testInviteUserInitialIdSiteError()
+ {
+ $this->expectException(\Exception::class);
+ $this->expectExceptionMessage("An unexpected website was found in the request: website id was set to '10'");
+ Request::processRequest(
+ 'UsersManager.inviteUser',
+ [
+ 'userLogin' => "testInviteUser",
+ 'email' => "testInviteUser@example.com",
+ 'initialIdSite' => 10,
+ 'expiryInDays' => 7,
+ ]
+ );
+ }
+
+
public function testInviteUserAsSuperUser()
{
$eventWasFired = false;
- EventDispatcher::getInstance()->addObserver('UsersManager.inviteUser.end', function ($userLogin, $email) use (&$eventWasFired) {
- self::assertEquals('pendingLoginTest', $userLogin);
- self::assertEquals('pendingLoginTest@matomo.org', $email);
- $eventWasFired = true;
- });
+ EventDispatcher::getInstance()->addObserver(
+ 'UsersManager.inviteUser.end',
+ function ($userLogin, $email) use (&$eventWasFired) {
+ self::assertEquals('pendingLoginTest', $userLogin);
+ self::assertEquals('pendingLoginTest@matomo.org', $email);
+ $eventWasFired = true;
+ }
+ );
$this->api->inviteUser('pendingLoginTest', 'pendingLoginTest@matomo.org', 1);
$user = $this->model->isPendingUser('pendingLoginTest');
@@ -1291,13 +1328,13 @@ class APITest extends IntegrationTestCase
public function testInviteUserExpiredInGivenDays()
{
- Date::$now = time(); // freeze time, so it doesn't change between inviting user and comparing the time
+ Date::$now = time(); // freeze time, so it doesn't change between inviting user and comparing the time
$expiredDays = 10;
- $this->api->inviteUser('pendingLoginTest', 'pendingLoginTest@matomo.org', null, $expiredDays);
- $user = $this->model->getUser('pendingLoginTest');
+ $this->api->inviteUser('pendingLoginTest', 'pendingLoginTest@matomo.org', 1, $expiredDays);
+ $user = $this->model->getUser('pendingLoginTest');
$expired = Date::factory($user['invite_expired_at'])->getTimestamp();
- $now = Date::now()->getTimestamp();
- $diff = $expired - $now;
+ $now = Date::now()->getTimestamp();
+ $diff = $expired - $now;
$this->assertEquals($expiredDays, $diff / 3600 / 24);
}
@@ -1309,10 +1346,13 @@ class APITest extends IntegrationTestCase
$eventWasFired = false;
- EventDispatcher::getInstance()->addObserver('UsersManager.inviteUser.resendInvite', function ($userLogin) use (&$eventWasFired) {
- self::assertEquals('pendingLoginTest', $userLogin);
- $eventWasFired = true;
- });
+ EventDispatcher::getInstance()->addObserver(
+ 'UsersManager.inviteUser.resendInvite',
+ function ($userLogin) use (&$eventWasFired) {
+ self::assertEquals('pendingLoginTest', $userLogin);
+ $eventWasFired = true;
+ }
+ );
$this->api->resendInvite('pendingLoginTest');
self::assertTrue($eventWasFired);
@@ -1337,10 +1377,13 @@ class APITest extends IntegrationTestCase
$eventWasFired = false;
- EventDispatcher::getInstance()->addObserver('UsersManager.inviteUser.resendInvite', function ($userLogin) use (&$eventWasFired) {
- self::assertEquals('pendingLoginTest', $userLogin);
- $eventWasFired = true;
- });
+ EventDispatcher::getInstance()->addObserver(
+ 'UsersManager.inviteUser.resendInvite',
+ function ($userLogin) use (&$eventWasFired) {
+ self::assertEquals('pendingLoginTest', $userLogin);
+ $eventWasFired = true;
+ }
+ );
$this->api->resendInvite('pendingLoginTest');
self::assertTrue($eventWasFired);
@@ -1437,7 +1480,7 @@ class APITest extends IntegrationTestCase
private function getAccessInSite($login, $idSite)
{
$access = $this->model->getSitesAccessFromUser($login);
- $ids = [];
+ $ids = [];
foreach ($access as $entry) {
if ($entry['site'] == $idSite) {
$ids[] = $entry['access'];
@@ -1454,22 +1497,26 @@ class APITest extends IntegrationTestCase
public function provideContainerConfig()
{
return [
- 'Piwik\Access' => new FakeAccess(),
- 'usersmanager.user_preference_names' => \DI\add([
- 'randomDoesNotExist',
- 'RandomNOTREQUESTED',
- 'preferenceName'
- ]),
- 'observers.global' => \DI\add([
- [
- 'Access.Capability.addCapabilities',
- \DI\value(function (&$capabilities) {
- $capabilities[] = new TestCap1();
- $capabilities[] = new TestCap2();
- $capabilities[] = new TestCap3();
- })
- ],
- ]),
+ 'Piwik\Access' => new FakeAccess(),
+ 'usersmanager.user_preference_names' => \DI\add(
+ [
+ 'randomDoesNotExist',
+ 'RandomNOTREQUESTED',
+ 'preferenceName',
+ ]
+ ),
+ 'observers.global' => \DI\add(
+ [
+ [
+ 'Access.Capability.addCapabilities',
+ \DI\value(function (&$capabilities) {
+ $capabilities[] = new TestCap1();
+ $capabilities[] = new TestCap2();
+ $capabilities[] = new TestCap3();
+ }),
+ ],
+ ]
+ ),
];
}
@@ -1486,7 +1533,7 @@ class APITest extends IntegrationTestCase
public function setCurrentUser($username, $accessLevel, $idSite)
{
- FakeAccess::$identity = $username;
+ FakeAccess::$identity = $username;
FakeAccess::$superUser = $accessLevel == 'superuser';
if ($accessLevel == 'view') {
FakeAccess::$idSitesView = is_array($idSite) ? $idSite : [$idSite];
diff --git a/plugins/UsersManager/tests/Integration/UserInviteTest.php b/plugins/UsersManager/tests/Integration/UserInviteTest.php
index 2c61bb90f4..792d4f8d0b 100644
--- a/plugins/UsersManager/tests/Integration/UserInviteTest.php
+++ b/plugins/UsersManager/tests/Integration/UserInviteTest.php
@@ -56,7 +56,7 @@ class UserInviteTest extends IntegrationTestCase
[
'userLogin' => $this->pendingUser['login'],
'email' => $this->pendingUser['email'],
- 'idSite' => 1,
+ 'initialIdSite' => 1,
'expiryInDays' => 7
]
);
diff --git a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_all_rows_in_search.png b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_all_rows_in_search.png
index fedb59b83e..78693a2697 100644
--- a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_all_rows_in_search.png
+++ b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_all_rows_in_search.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:c231e9609f5928426cf71151d703557a0fafc08eb9ece4a1447149c966925c21
-size 100235
+oid sha256:e485f985a2096bfc259e9955a008ebd5879ee9725f691b1d4c5f10fd4d1dc73b
+size 86742
diff --git a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_edit.png b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_edit.png
index faf8d32988..659afa6579 100644
--- a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_edit.png
+++ b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_permissions_edit.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:292e3f739530aad0ceba658f55e123556c845ec681ccc2f77244184028ef35cb
-size 88585
+oid sha256:6a9b4f7b1ac46e2521631fa7055f94fe921c7088af7307191b0a1ef9bb0b6b46
+size 75169
diff --git a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_user_created.png b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_user_created.png
index 9184f1a37d..0d4934988b 100644
--- a/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_user_created.png
+++ b/plugins/UsersManager/tests/UI/expected-screenshots/UsersManager_user_created.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:f97cfaa64c56e51a88d1f4727be80753f5e51956fd474d4d1ec89a5dfd0d5508
-size 22833
+oid sha256:406437e042339b681e39ce9e745e8ee5e391fd758a3bee0b8a1651a9c80f5c96
+size 22488
diff --git a/tests/UI/expected-screenshots/UIIntegrationTest_api_listing.png b/tests/UI/expected-screenshots/UIIntegrationTest_api_listing.png
index 9bd04f9175..842a39ee1c 100644
--- a/tests/UI/expected-screenshots/UIIntegrationTest_api_listing.png
+++ b/tests/UI/expected-screenshots/UIIntegrationTest_api_listing.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:1d17357b1e8a3a7ea193d56a633eba6f563ff2d4f8ee008574d14abb8dbc8a38
-size 5077474
+oid sha256:5c3a0bbfd3f780aa41cb1914832e7c0389c81594752111c9698dd8d5759634fb
+size 5077766