636 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			636 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /*eslint no-undef:0*/
 | |
| /*eslint-env browser*/
 | |
| 
 | |
| "use strict";
 | |
| var apx = apx || {};
 | |
| 
 | |
| /**************************************************************************
 | |
|  * apx.js manage data to interact with an apxtri instance from a webpage *
 | |
|  * component can be add with name-wco
 | |
|  *************************************************************************
 | |
|  * This code is not minify and target to be understood by a maximum of 
 | |
|  * curious people to audit and give any feedback to support@ndda.fr 
 | |
|  * 
 | |
|  * To audit it in a browser like chrome:
 | |
|  *  - open web developpement (F12)
 | |
|  *  - Menu Sources: apx.js , see below for more information
 | |
|  *  -             : apxid.js, this is the authentification module that works as a microservice  
 | |
|  *  
 | |
|  * 
 | |
|  * Main principle:
 | |
|  * - Usage of localStorage to store any usefull data and save it between session
 | |
|  * - All data and template can be download from an apxtri
 | |
|  *     get /api/apxtri/wwws/updatelocaldb{ano}/{tribe}/{xapp}/{pagename}/{version} 
 | |
|  *     ano = empty if authenticated anonymous if not
 | |
|  *     tribe = the tribe where tha xapp is strore
 | |
|  *     xapp = the folder name in /tribe/xapp/
 | |
|  *     pagename = the name of the page without _xx (language)
 | |
|  *     version = 0 or the version currently store (version is to manage cach)
 | |
|  * 
 | |
|  * ------------------
 | |
|  * ? State management
 | |
|  * ------------------
 | |
|  * html page must have apxtri with at least headers key
 | |
|  * 
 | |
|     <script>
 | |
|       const apxtri={
 | |
|        version:0, // 0 mean it is a first visit if you force to 0 then it will reload all app data
 | |
|        pagename:"pagename", // without _lg.html ex:pageadmin
 | |
|        pageauth:"apxid" local page with authentification without _lg,
 | |
|        headers:{
 | |
|         xalias:"anonymous",
 | |
|         xhash:"anonymous",
 | |
|         xtribe:"tribeId",
 | |
|         xapp:"app name",
 | |
|         xlang:"en",
 | |
|         xdays:0,
 | |
|         xuuid:"0",
 | |
|         xtrkversion:1}
 | |
|        }
 | |
|        wco:{}
 | |
|        //specific init data for this webpage 
 | |
|     } ;
 | |
|     </script>   
 | |
|  * ++++++++   
 | |
|  * ? apx.ready(callback) await DOM is ready equivalent of jquery Document.ready()
 | |
|  * +++++++++  
 | |
|  * ? apx.readyafterupdate(callback) allow to add function callback that will be load after apx.ready to add a function to execute  apx.readyafterupdate(functname) without () after functname
 | |
|  * +++++++++ 
 | |
|  * ? apx.listendatawco(newpropertie) allow to store data in apx.data.wco and to listen any change to update HTML DOM content <tag data-wco="propertie"></tag> if apx.data.wco.propertie value change then it change every where data-wco=propertie exist innerHTML, textContent, class, ...value
 | |
|  * to add a new propertie to listen just add it apx.data.wco.propertie={innerHTML:"<p>test</p>"} and run apx.listendatawco(propertie)
 | |
|  * +++++++++
 | |
|  * ? apx.notification(selector, data) insert in tag selector an apx return call into data{status:xxx,ref:"Ref",msg:"key",data:{}}, it use apx.data.ref[data.ref].msg as template and render it with data 
 | |
|  * +++++++++
 | |
|  * ? apx.save() save apx.data as {xapp} value in localStorage to be able for the same domain to share data
 | |
|  * +++++++++
 | |
|  * ? apx.update() :
 | |
|  * Run at least once after loading a pagename, what it does:   
 | |
|  * - url/page.html?k1=v1&k2=v2#h1=v4&h2=v5 => store in apx.pagecontext = { search: {k1:v1,k2:v2}, hash: {h1:v4,h2:v5} };
 | |
|  * - updatelocaldb from api to localstorage name xapp (options / ref / schema / tpl /tpldata) store in {tribe}/wwws/{xapp}.json with key {pagename}
 | |
|  * - run apx.listendatawco() to allow any apx.data.wco variable to update DOM
 | |
|  * - run any function that were store in apx.afterupdate.
 | |
|  * - run apx.lazyload() to load image in background (this is to decrease time loading for search engine)
 | |
|  * ++++++++++
 | |
|  * */
 | |
| 
 | |
| apx.ready = (callback) => {
 | |
|   if (!callback) {
 | |
|     alert(
 | |
|       "You have an unknown callback apx.ready(callback), you need to order your code callback = ()=>{} then apx.ready(callback), boring but js rules ;-)"
 | |
|     );
 | |
|   }
 | |
|   if (document.readyState != "loading") callback();
 | |
|   // modern browsers
 | |
|   else if (document.addEventListener)
 | |
|     document.addEventListener("DOMContentLoaded", callback);
 | |
|   // IE <= 8
 | |
|   else
 | |
|     document.attachEvent("onreadystatechange", function () {
 | |
|       if (document.readyState == "complete") callback();
 | |
|     });
 | |
| };
 | |
| 
 | |
| apx.readyafterupdate = (callback) => {
 | |
|   if (!apx.afterupdate) apx.afterupdate = [];
 | |
|   apx.afterupdate.push(callback);
 | |
| };
 | |
| 
 | |
| apx.lazyload = () => {
 | |
|   document.querySelectorAll("img[data-lazysrc]").forEach((e) => {
 | |
|     //  in src/page.html:  src contain original img and data-lazysrc='true'
 | |
|     //  in dist/page.html src is removed img src is in data-lazysrc=newimage.webp or svg
 | |
|     let src = e.getAttribute("src")
 | |
|       ? e.getAttribute("src")
 | |
|       : e.getAttribute("data-lazysrc");
 | |
|     if (e.getAttribute("data-trksrckey")) {
 | |
|       src = `/trk/${src}?alias=${apx.data.headers.xalias}&uuid=${
 | |
|         apx.data.headers.xuuid
 | |
|       }&srckey=${e.getAttribute("data-trksrckey")}&version=${
 | |
|         apx.data.headers.xtrkversion
 | |
|       }&consentcookie=${localStorage.getItem("consentcookie")}&lg=${
 | |
|         apx.data.headers.xlang
 | |
|       }`;
 | |
|     }
 | |
|     e.setAttribute("src", src);
 | |
|     console.log("lazyload track:", src);
 | |
|     e.removeAttribute("data-lazysrc");
 | |
|   });
 | |
|   document.querySelectorAll("[data-lazybgsrc]").forEach((e) => {
 | |
|     e.style.backgroundImage = `url(${e.getAttribute("src")})`;
 | |
|     e.removeAttribute("data-lazybgsrc");
 | |
|   });
 | |
|   document.querySelectorAll("a[data-trksrckey]").forEach((e) => {
 | |
|     let urldestin = e.getAttribute("href");
 | |
|     if (
 | |
|       urldestin.substring(0, 4) != "http" &&
 | |
|       urldestin.substring(0, 1) != "/"
 | |
|     ) {
 | |
|       urldestin = "/" + urldestin;
 | |
|     }
 | |
|     const hreftrack = `/trk/redirect?alias=${apx.data.headers.xalias}&uuid=${
 | |
|       apx.data.headers.xuuid
 | |
|     }&srckey=${e.getAttribute("data-trksrckey")}&version=${
 | |
|       apx.data.headers.xtrkversion
 | |
|     }&consentcookie=${localStorage.getItem("consentcookie")}&lg=${
 | |
|       apx.data.headers.xlang
 | |
|     }&url=${urldestin}`;
 | |
|     console.log("href track:", hreftrack);
 | |
|     e.setAttribute("href", hreftrack);
 | |
|     e.removeAttribute("data-trksrckey");
 | |
|   });
 | |
| };
 | |
| apx.notification = (selector, data, clearbefore) => {
 | |
|   /**
 | |
|    * @selector a text to use querySelector() in document
 | |
|    * @data apxtri return from any request {status:200,ref:"",msg:"key", data }
 | |
|    *   if {status,multimsg:[{ref,msg,data}]} then a multi feedback are in
 | |
|    * @clearbefore boolean if true then it remove the previous message
 | |
|    * @return update the dom selctor with the relevant render message in the relevant language
 | |
|    */
 | |
|   console.log("notification of ", data);
 | |
|   const el = document.querySelector(selector);
 | |
|   if (!el) {
 | |
|     console.log(
 | |
|       `WARNING !!! check apx.notification selector:${selector} does not exist in this page`
 | |
|     );
 | |
|     return false;
 | |
|   }
 | |
|   if (clearbefore) el.innerHTML = "";
 | |
|   const multimsg = data.multimsg ? data.multimsg : [data];
 | |
|   multimsg.forEach((info) => {
 | |
|     if (!apx.data.ref[info.ref]) {
 | |
|       console.log(
 | |
|         `check apx.data.ref, ${info.ref} does not exist in this page, add it `
 | |
|       );
 | |
|       return false;
 | |
|     } else if (!apx.data.ref[info.ref][info.msg]) {
 | |
|       console.log(
 | |
|         `check apx.data.ref.${info.ref} does not contain ${info.msg} update /schema/lg or /model/lg`
 | |
|       );
 | |
|       return false;
 | |
|     }
 | |
|     el.innerHTML +=
 | |
|       " " + Mustache.render(apx.data.ref[info.ref][info.msg], info.data);
 | |
|     if (data.status == 200) {
 | |
|       el.classList.remove("text-red");
 | |
|       el.classList.add("text-green");
 | |
|     } else {
 | |
|       el.classList.add("text-red");
 | |
|       el.classList.remove("text-green");
 | |
|     }
 | |
|   });
 | |
| };
 | |
| apx.listendatawco = (newpropertie) => {
 | |
|   // listen any change in apx.wco.newpropertie and update interface with this new value
 | |
|   //  < data-wco="propertie of apx.wco"> is updated with content text, html any attribute in this new value
 | |
|   // to init run apx.listendatawco() this is done by apx.update()
 | |
|   // to dynamicaly add a new propertie to listen just run apx.listendatawco(propertietoadd);
 | |
|   // Then manage your data by modifying apx.wco and it will be update anywhere it use in the webpage
 | |
|   //example:
 | |
|   //  <img data-wco="logodetoto" src="urltoimage" "alt">
 | |
|   //  apx.wco.logodetoto={src:"newurltoimage",alt:"newalt"} then it will change every where data-wco=logodetoto
 | |
|   //
 | |
|   //  <p data-wco="claim">Blabla</p>
 | |
|   //  apx.wco.claim={html:"newblabla"}
 | |
|   console.log("From apx.data.wco:", apx.data.wco);
 | |
|   if (!apx.wco) apx.wco = {};
 | |
|   console.log(
 | |
|     "wco dynamic into the webpage",
 | |
|     apx.data.wco,
 | |
|     "no propertie to add:",
 | |
|     !newpropertie
 | |
|   );
 | |
|   if (!apx.data.wco || Object.keys(apx.data.wco).length == 0) return false;
 | |
|   newpropertie = !newpropertie ? Object.keys(apx.data.wco) : [newpropertie];
 | |
|   console.log("listen apx.data.wco properties:", newpropertie);
 | |
|   newpropertie.forEach((p) => {
 | |
|     const actionprop = (val, elt) => {
 | |
|       if (val.innerHTML) elt.innerHTML = val.innerHTML;
 | |
|       if (val.textContent) elt.textContent = val.textContent;
 | |
|       for (const h in ["innerHTML", "textContent"]) {
 | |
|         if (val[h]) elt[h] = val[h];
 | |
|       }
 | |
|       for (const a in ["src", "alt", "placeholder", "class", "href"]) {
 | |
|         if (val[a]) elt.setAttribute(a, val[a]);
 | |
|       }
 | |
|     };
 | |
|     const elements = document.querySelectorAll(`[data-wco='${p}']`);
 | |
|     elements.forEach((e) => actionprop(apx.data.wco[p], e));
 | |
|     //console.log(p, Object.hasOwnProperty(apx.wco));
 | |
|     if (!apx.data.wco.hasOwnProperty(p)) {
 | |
|       let _val = apx.data.wco[p]; // Stocke la valeur initiale
 | |
|       Object.defineProperty(apx.data.wco, p, {
 | |
|         get: () => _val,
 | |
|         set: (newv) => {
 | |
|           _val = newv; // Met à jour la valeur interne
 | |
|           const elements = document.querySelectorAll(`[data-wco='${p}']`); // Re-sélectionne les éléments au cas où le DOM aurait changé
 | |
|           elements.forEach((e) => actionprop(newv, e));
 | |
|         },
 | |
|       });
 | |
|       if (_val !== undefined) {
 | |
|         apx.data.wco[p] = _val;
 | |
|       }
 | |
|     }
 | |
|   });
 | |
| };
 | |
| apx.wcoobserver = () => {
 | |
|   /**
 | |
|    * wco web component observer if apxtri.wcoobserver==true,
 | |
|    * Observe existing or creation of any element in DOM with <div wco-name="wconame" id="uniqueid" wco-YYY="aa"></div>
 | |
|    * if create or if any wco-YYY value change it runs apx[wconame].loadwco(id,ctx) where ctx={YYY:aa}
 | |
|    * Example:
 | |
|    * <div id="monComponent" wco-name="monComposant" wco-screen="dashboard" wco-theme="dark" wco-ref="123"></div>
 | |
|    * if innerHTML this OR if any wco-YYYY change =>
 | |
|    *      run apx.monComposant.loadwco('monComponent',
 | |
|    *                                   {'wco-name': 'monComposant',
 | |
|    *                                    'wco-screen': 'dashboard',
 | |
|    *                                    'wco-theme': 'dark',
 | |
|    *                                    'wco-ref': '123'});
 | |
|    * Used with wco component manage in apx to communicate between autonomous component to reload content if contexte change.
 | |
|    * Typical example of a wco menu that will load another wco content if not exist and will change a wco-screen to change the content of the wco content
 | |
|    */
 | |
|   console.log("listen wcoobserver");
 | |
|   const processElement = (element) => {
 | |
|     if (element.nodeType === 1 && element.tagName === "DIV") {
 | |
|       if (element.id && element.hasAttribute("wco-name")) {
 | |
|         const ctx = {};
 | |
|         for (const attr of element.attributes) {
 | |
|           if (attr.name.startsWith("wco-")) {
 | |
|             ctx[attr.name.slice(4)] = attr.value;
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         const wcoName = element.getAttribute("wco-name");
 | |
|         if (apx[wcoName] && typeof apx[wcoName].loadwco === "function") {
 | |
|           apx[wcoName].loadwco(element.id, ctx);
 | |
|         } else {
 | |
|           console.log(`ERROR: apx.${wcoName}.loadwco() not found`);
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     // Process children recursively
 | |
|     if (element.children) {
 | |
|       Array.from(element.children).forEach(processElement);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   const observer = new MutationObserver((mutations) => {
 | |
|     mutations.forEach((mutation) => {
 | |
|       if (mutation.type === "childList") {
 | |
|         mutation.addedNodes.forEach((node) => {
 | |
|           processElement(node);
 | |
|         });
 | |
|       }
 | |
| 
 | |
|       if (
 | |
|         mutation.type === "attributes" &&
 | |
|         mutation.attributeName.startsWith("wco-")
 | |
|       ) {
 | |
|         const element = mutation.target;
 | |
|         if (element.id && element.hasAttribute("wco-name")) {
 | |
|           const ctx = {};
 | |
|           for (const attr of element.attributes) {
 | |
|             if (attr.name.startsWith("wco-")) {
 | |
|               ctx[attr.name.slice(4)] = attr.value;
 | |
|             }
 | |
|           }
 | |
| 
 | |
|           const wcoName = element.getAttribute("wco-name");
 | |
|           if (apx[wcoName] && typeof apx[wcoName].loadwco === "function") {
 | |
|             apx[wcoName].loadwco(element.id, ctx);
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     });
 | |
|   });
 | |
| 
 | |
|   observer.observe(document.body, {
 | |
|     childList: true,
 | |
|     subtree: true,
 | |
|     attributes: true, // <-- active la détection de changements d'attributs
 | |
|   });
 | |
| 
 | |
|   // Pour les éléments déjà présents au chargement
 | |
|   document.addEventListener("DOMContentLoaded", () => {
 | |
|     document.querySelectorAll("div[wco-name]").forEach((element) => {
 | |
|       if (element.id) {
 | |
|         const ctx = {};
 | |
|         for (const attr of element.attributes) {
 | |
|           if (attr.name.startsWith("wco-")) {
 | |
|             ctx[attr.name.slice(4)] = attr.value;
 | |
|           }
 | |
|         }
 | |
|         const wcoName = element.getAttribute("wco-name");
 | |
|         console.log(`load observer of wco for ${wcoName} in id=${element.id}`);
 | |
|         if (apx[wcoName] && typeof apx[wcoName].loadwco === "function") {
 | |
|           apx[wcoName].loadwco(element.id, ctx);
 | |
|         }
 | |
|       }
 | |
|     });
 | |
|   });
 | |
|   //load existing wco-name in the html page to initiate the wco process
 | |
|   // it read and write the wco-name that will trig the observer as a change
 | |
|   document.querySelectorAll("div[wco-name]").forEach((e) => {
 | |
|     const wconame = e.getAttribute("wco-name");
 | |
|     console.log("load wco-name:", wconame);
 | |
|     e.setAttribute("wco-name", wconame);
 | |
|   });
 | |
| };
 | |
| apx.managecontext = () => {
 | |
|   // Set authenticate parameter if in pagecontext and redirect to the requested url
 | |
|   console.log(
 | |
|     apx.pagecontext.hash.xdays,
 | |
|     apx.pagecontext.hash.xprofils,
 | |
|     apx.pagecontext.hash.xtribe,
 | |
|     dayjs(apx.pagecontext.hash.xdays),
 | |
|     dayjs(apx.pagecontext.hash.xdays).diff(dayjs(), "hours") < 25,
 | |
|     apx.pagecontext.hash.xhash
 | |
|   );
 | |
|   if (
 | |
|     apx.pagecontext.hash.xhash &&
 | |
|     apx.pagecontext.hash.xdays &&
 | |
|     apx.pagecontext.hash.xprofils &&
 | |
|     apx.pagecontext.hash.xtribe &&
 | |
|     dayjs(apx.pagecontext.hash.xdays) &&
 | |
|     dayjs(apx.pagecontext.hash.xdays).diff(dayjs(), "hours") < 25
 | |
|   ) {
 | |
|     //Means this page is called from an external auth app
 | |
|     let headervalid = true;
 | |
|     headerkey.forEach((h) => {
 | |
|       if (apx.pagecontext.hash[h]) {
 | |
|         apx.data.headers[h] =
 | |
|           h === "xprofils"
 | |
|             ? apx.pagecontext.hash[h].split(",")
 | |
|             : apx.pagecontext.hash[h];
 | |
|       } else {
 | |
|         headervalid = false;
 | |
|       }
 | |
|     });
 | |
|     console.log(headervalid, apx.data.headers);
 | |
|     if (headervalid) {
 | |
|       apx.save();
 | |
|       if (apx.pagecontext.hash.url) {
 | |
|         window.location.href = apx.pagecontext.hash.url;
 | |
|       }
 | |
|     } else {
 | |
|       console.log("Your try to access a page failled with ", apx.pagecontext);
 | |
|     }
 | |
|   }
 | |
| };
 | |
| // State management
 | |
| apx.save = () => {
 | |
|   localStorage.setItem(apx.data.headers.xapp, JSON.stringify(apx.data));
 | |
| };
 | |
| apx.update = async () => {
 | |
|   if (!apxtri || !apxtri.headers || !apxtri.headers.xapp) {
 | |
|     console.log(
 | |
|       'Please add to the html page header, this line  const apxtri = { headers: { xtrkversion: 1, xtribe: "smatchit", xapp: "pwa", xlang: "fr", xalias: "anonymous", xhash: "anonymous", xdays: 0} ,pagename:"apxid"} '
 | |
|     );
 | |
|     return;
 | |
|   }
 | |
|   const headerkey = ["xalias", "xhash", "xdays", "xprofils", "xtribe", "xlang"];
 | |
|   if (document.querySelector("html").getAttribute("lang")) {
 | |
|     apxtri.headers.xlang = document.querySelector("html").getAttribute("lang");
 | |
|   }
 | |
|   apxtri.headers.xlang = apxtri.headers?.xlang || "en";
 | |
|   //Get if exist in localstorage a key apxtri.headers.xapp
 | |
|   if (apxtri.headers.xapp && localStorage.getItem(apxtri.headers.xapp)) {
 | |
|     apx.data = JSON.parse(localStorage.getItem(apxtri.headers.xapp));
 | |
|     //update with current pagename and eventualy pageauth
 | |
|     apx.data.pagename = apxtri.pagename;
 | |
|     if (apxtri.pageauth) apx.data.pageauth = apxtri.pageauth;
 | |
|     const isauth = await axios.get('/api/apxtri/pagans/isauth', { headers: apx.data.headers,  withCredentials:true,validateStatus: (status) => true});
 | |
|     if (
 | |
|       (isauth.status!==200 && apx.data.headers.alias!=="anonymous") ||
 | |
|       apx.data.headers.xtribe != apxtri.headers.xtribe ||
 | |
|       apx.data.headers.xlang != apxtri.headers.xlang ||
 | |
|       apx.data.headers.xtrkversion != apxtri.headers.xtrkversion
 | |
|     ) {
 | |
|       // if no more authenticated or change of tribe...
 | |
|       localStorage.removeItem(apxtri.headers.xapp);
 | |
|       delete apx.data;
 | |
|     }
 | |
|   }
 | |
|   //reinit if apx.data does not exist
 | |
|   apx.data = apx?.data || apxtri;
 | |
|   // get context from url search ?q=x&s=z or hash #q=x&s=z
 | |
|   // search comme from a reloading page instead of hash is just a passive link
 | |
|   apx.pagecontext = { search: {}, hash: {} };
 | |
|   ["hash", "search"].forEach((type) => {
 | |
|     const paramString = window.location[type];
 | |
|     if (paramString) {
 | |
|       paramString
 | |
|         .slice(1)
 | |
|         .split("&")
 | |
|         .forEach((kv) => {
 | |
|           const [key, value] = kv.split("=");
 | |
|           apx.pagecontext.hash[key] = value;
 | |
|         });
 | |
|     }
 | |
|   });
 | |
|   console.log("apx.pagecontext:", apx.pagecontext);
 | |
| 
 | |
|   // check is authenticated
 | |
|   if (
 | |
|     apx.data.headers.xalias === "anonymous" ||
 | |
|     (apx.pagecontext.hash.xdays &&
 | |
|       dayjs(apx.pagecontext.hash.xdays).diff(dayjs(), "hours") < 25)
 | |
|   ) {
 | |
|     // reset authentification data
 | |
|     apx.data.headers.xalias = "anonymous";
 | |
|     apx.data.headers.xdays = 0;
 | |
|     apx.data.headers.xprofils = ["anonymous"];
 | |
|     delete apx.data.headers.xhash;
 | |
|   }
 | |
|   //apx.managecontext(); (todo when all work target is to use context to redirect if key word used in contexte url, ....)
 | |
|   if (
 | |
|     apx.data.headers.xalias === "anonymous" &&
 | |
|     (apx.data.auth || !apx.data.allowedprofils.includes("anonymous"))
 | |
|   ) {
 | |
|     // Means user is not authenticat and has a rememberMe previously selected (auth) OR this page is not accessible to an anonymous.
 | |
|     // Redirect to apxid page if auth is ok then redirect to this page
 | |
|     //                           notauth then expected to have alias privatekey
 | |
|     //document.location.href = `/apxtriadmin/${apx.data.pageauth}_${apx.data.headers.xlang}.html#url=${apx.data.
 | |
|     document.location.href = `/apxtriadmin/apxid_${apx.data.headers.xlang}.html#url=${apx.data.pagename}_${apx.data.headers.xlang}.html`;
 | |
|   }
 | |
| 
 | |
|   // check accessright to the page
 | |
|   if (
 | |
|     apx.data.allowedprofils &&
 | |
|     !apx.data.allowedprofils.includes("anonymous") &&
 | |
|     apx.data.pagename !== apx.data.pageauth
 | |
|   ) {
 | |
|     const profilintersect = apx.data.allowedprofils.filter((x) =>
 | |
|       apx.data.headers.xprofils.includes(x)
 | |
|     );
 | |
|     console.log("profils authorized:", profilintersect);
 | |
|     if (profilintersect.length == 0) {
 | |
|       alert(apx.data.ref.Middlewares.notallowtoaccess);
 | |
|       document.location.href = `/apxtriadmin/apxid_${apx.data.headers.xlang}.html`
 | |
|       return false;
 | |
|     }
 | |
|   }
 | |
|   console.log("authorized to access");
 | |
|   /* à voir si utile redirect to authentification page pageauth with a redirection if authentify to the pagename (check if /src/ then add it)
 | |
|   window.location.href = `${apxtri.pageauth}_${
 | |
|     apxtri.headers.xlang
 | |
|   }.html?url=${window.location.href.includes("/src/") ? "/src/" : ""}${
 | |
|     apxtri.pagename
 | |
|   }_${apxtri.headers.xlang}.html`;
 | |
|   */
 | |
|   /// axios setting //
 | |
|   axios.defaults.withCredentials = true; // force to send cookie http only for authentification
 | |
|   axios.defaults.headers.common=apx.data.headers;
 | |
|   ////////////////////
 | |
| 
 | |
|   ////////////////////////////////////////////
 | |
|   apx.data.version = 0; //this force an update to be removed in production
 | |
|   ///////////////////////////////////////////
 | |
|   const ano = apx.data.headers.xalias == "anonymous" ? "anonymous" : "";
 | |
|   const initdb = `/api/apxtri/wwws/updatelocaldb${ano}/${apx.data.headers.xtribe}/${apx.data.headers.xapp}/${apx.data.pagename}/${apx.data.version}`;
 | |
|   let initset = {};
 | |
|   try {
 | |
|     initset = await axios.get(initdb, {
 | |
|       timeout: 2000
 | |
|     });
 | |
|   } catch (err) {
 | |
|     console.log(err);
 | |
|     initset = { data: { msg: "unavailableAPI" } };
 | |
|   }
 | |
|   console.log("recupe inidb for ", initdb, initset);
 | |
|   if (initset.data.msg == "forbidenaccess") {
 | |
|     alert(apx.data.ref.Middlewares.notallowtoaccess);
 | |
|     return false;
 | |
|   }
 | |
|   if (initset.data.msg == "unavailableAPI") {
 | |
|     console.log("Your api endpoint is down check your hosted server");
 | |
|     //try again in 30 seconds
 | |
|     setTimeout(apx.update, 30000);
 | |
|   }
 | |
|   if (initset.data.msg == "data_model_update") {
 | |
|     Object.keys(initset.data.data).forEach((k) => {
 | |
|       if (k !== "headers") {
 | |
|         apx.data[k] = initset.data.data[k];
 | |
|       }
 | |
|     });
 | |
|     console.log("local update done");
 | |
|     apx.save();
 | |
|   }
 | |
| 
 | |
|   apx.listendatawco(); // listen any data-wco tag and update it when apxdatawco propertie change
 | |
|   if (apxtri.wcoobserver) apx.wcoobserver();
 | |
|   if (apx.afterupdate) apx.afterupdate.forEach((cb) => cb()); //run all function store in apx.afterupdate in order
 | |
|   apx.lazyload(); //reload image or any media that takes time to load to improve engine search
 | |
|   apx.save(); //store in local the modification
 | |
| };
 | |
| apx.ready(apx.update); //2nd param optional=> true mean does not wait same if apx.lock is set
 | |
| 
 | |
| apx.indexedDB = apx.indexedDB || {};
 | |
| 
 | |
| apx.indexedDB.set = async (db, storeName, value) => {
 | |
|   return new Promise((resolve, reject) => {
 | |
|     const request = indexedDB.open(db, 1);
 | |
| 
 | |
|     request.onupgradeneeded = (event) => {
 | |
|       const db = event.target.result;
 | |
| 
 | |
|       if (!db.objectStoreNames.contains("threads")) {
 | |
|         db.createObjectStore("threads", { keyPath: "uuid" });
 | |
|       }
 | |
| 
 | |
|       if (!db.objectStoreNames.contains("messages")) {
 | |
|         db.createObjectStore("messages", { keyPath: "privatriid" });
 | |
|       }
 | |
|     };
 | |
| 
 | |
|     request.onsuccess = (event) => {
 | |
|       const db = event.target.result;
 | |
| 
 | |
|       if (!db.objectStoreNames.contains(storeName)) {
 | |
|         return resolve();
 | |
|       }
 | |
| 
 | |
|       const transaction = db.transaction(storeName, "readwrite");
 | |
|       const store = transaction.objectStore(storeName);
 | |
| 
 | |
|       const putRequest = store.put(value);
 | |
|       putRequest.onsuccess = () => resolve();
 | |
|       putRequest.onerror = (error) => reject(error);
 | |
|     };
 | |
| 
 | |
|     request.onerror = (error) => reject(error);
 | |
|   });
 | |
| };
 | |
| 
 | |
| apx.indexedDB.get = async (db, storeName, key) => {
 | |
|   return new Promise((resolve, reject) => {
 | |
|     const request = indexedDB.open(db, 1);
 | |
| 
 | |
|     request.onsuccess = (event) => {
 | |
|       const db = event.target.result;
 | |
|       if (!db.objectStoreNames.contains(storeName)) {
 | |
|         return resolve(null);
 | |
|       }
 | |
|       const transaction = db.transaction(storeName, "readonly");
 | |
|       const store = transaction.objectStore(storeName);
 | |
| 
 | |
|       const getRequest = store.get(key);
 | |
| 
 | |
|       getRequest.onsuccess = () => {
 | |
|         resolve(getRequest.result || null);
 | |
|       };
 | |
| 
 | |
|       getRequest.onerror = () => resolve(null);
 | |
|     };
 | |
| 
 | |
|     request.onerror = (error) => reject(error);
 | |
|   });
 | |
| };
 | |
| 
 | |
| apx.indexedDB.del = async (db, storeName, key) => {
 | |
|   return new Promise((resolve, reject) => {
 | |
|     const request = indexedDB.open(db, 1);
 | |
| 
 | |
|     request.onsuccess = (event) => {
 | |
|       const db = event.target.result;
 | |
| 
 | |
|       if (!db.objectStoreNames.contains(storeName)) {
 | |
|         return resolve();
 | |
|       }
 | |
| 
 | |
|       const transaction = db.transaction(storeName, "readwrite");
 | |
|       const store = transaction.objectStore(storeName);
 | |
| 
 | |
|       const deleteRequest = store.delete(key);
 | |
|       deleteRequest.onsuccess = () => resolve();
 | |
|       deleteRequest.onerror = (error) => reject(error);
 | |
|     };
 | |
| 
 | |
|     request.onerror = (error) => reject(error);
 | |
|   });
 | |
| };
 | |
| 
 | |
| apx.indexedDB.getAllKeys = async (db, storeName) => {
 | |
|     return new Promise((resolve, reject) => {
 | |
|         const request = indexedDB.open(db, 1);
 | |
| 
 | |
|         request.onsuccess = (event) => {
 | |
|             const db = event.target.result;
 | |
| 
 | |
|             const transaction = db.transaction(storeName, "readonly");
 | |
|             const store = transaction.objectStore(storeName);
 | |
| 
 | |
|             const keysRequest = store.getAllKeys();
 | |
| 
 | |
|             keysRequest.onsuccess = (event) => {
 | |
|                 resolve(event.target.result);
 | |
|             };
 | |
| 
 | |
|             keysRequest.onerror = (event) => {
 | |
|                 reject(event);
 | |
|             };
 | |
|         };
 | |
| 
 | |
|         request.onerror = (error) => reject(error);
 | |
|     });
 | |
| } |