update project with new architecture

This commit is contained in:
2023-04-13 07:46:35 +02:00
parent d0a3b10cfe
commit 67a02c33a2
333 changed files with 3764 additions and 1254 deletions

View File

@@ -0,0 +1,216 @@
"use strict";
var pwa = pwa || {};
/*
Manage user authentification and registration
________________________
pwa.auth.route()
manage from state.json route if authenticated or not
redirect public page or app page
________________________
pwa.auth.screenlogin()
show login modal
________________________
pwa.auth.getlinkwithoutpsw()
special get with token and uuid workeable for 24h this link is une onetime
_________________________
pwa.auth.isAuthenticate()
test if token is still ok or not return false/true
_________________________
pwa.auth.authentification({LOGIN,PASSWORD})
if ok => load pwa.state.data.app .headers .userlogin
_________________________
pwa.auth.login()
Manage login modal to get login psw value and submit it to pwa.auth.authentification()
_________________________
pwa.auth.logout()
Remove localstorage and reload
_________________________
pwa.auth.register()
@TODO
__________________________
pwa.auth.forgetpsw()
Request to send an email with a unique get link to access from this link to the app
*/
/*MODULEJS*/
//--##
pwa.auth = {};
// Refresh browser state if exist else get pwa.state defaults
//pwa.state.ready( pwa.auth.check );
pwa.auth.Checkjson = () => {
if( pwa.state.data.login.isAuthenticated ) {
if( !pwa.auth.isAuthenticate() ) {
// Then reinit local storage and refresh page
pwa.state.data.login.isAuthenticated = false;
pwa.state.save();
//alert( 'reload page cause no more auth' )
window.location.reload();
};
}
};
pwa.auth.route = ( destination ) => {
console.log( 'auth.route to', destination );
//if check Authenticated && exist #signin button[data-routeto] then redirect browser to button[data-routeto]
//else manage component action auth
if( pwa.state && pwa.state.data && pwa.state.data.login && pwa.state.data.login.isAuthenticated ) {
if( destination )
window.location.pathname = `${pwa.state.data.ctx.urlbase}/${destination}`;
} else {
[ "#signin", "#resetpsw", "#register" ].forEach( e => {
if( e == destination ) {
document.querySelector( e )
.classList.remove( 'd-none' );
} else {
document.querySelector( e )
.classList.add( 'd-none' );
}
} )
}
}
pwa.auth.isAuthenticate = async function () {
// in any request, if middleware isAuthenticated return false
// then headers Xuuid is set to 1
// then try pwa.auth.isAuthenticate if rememberMe auto reconnect
// if jwt is ok then return true in other case => false
// this is the first test then depending of action see ACCESSRIGHTS of user
console.log( 'lance isauth', {
headers: pwa.state.data.headers.xpaganid
} )
//alert( 'uuid ' + pwa.state.data.headers.xpaganid )
console.log( `https://${pwa.state.data.ctx.urlbackoffice}/users/isauth`, {
headers: pwa.state.data.headers
} )
try {
const repisauth = await axios.get( `https://${pwa.state.data.ctx.urlbackoffice}/users/isauth`, {
headers: pwa.state.data.headers
} )
console.log( repisauth )
console.log( 'isAauthenticate: yes' )
return true;
} catch ( err ) {
if( err.response ) { console.log( "response err ", err.response.data ) }
if( err.request ) { console.log( "request err", err.request ) }
console.log( 'isAuthenticate: no' )
pwa.state.data.headers.xpaganid = "1";
if( pwa.state.data.login.rememberMe.login ) {
if( await pwa.auth.authentification( pwa.state.data.login.rememberMe ) ) {
return await pwa.auth.isAuthenticate();
};
}
return false;
}
};
pwa.auth.authentification = async function ( data ) {
// Core client function to chech auth from login & psw
// In case of 403 error lauch pwa.authentification(pwa.app.rememberMe)
// in case of sucess update paw.state.data.login
console.groupCollapsed( "Post Authentification for standard on : https://" + pwa.state.data.ctx.urlbackoffice + "/users/login param data", data )
console.log( 'header de login', pwa.state.data.headers )
let auth;
try {
auth = await axios.post( `https://${pwa.state.data.ctx.urlbackoffice }/users/login`, data, {
headers: pwa.state.data.headers
} );
console.log( "retour de login successfull ", auth );
//Maj variable globale authentifié
pwa.state.data.headers.xpaganid = auth.data.payload.data.UUID;
pwa.state.data.headers.xauth = auth.data.payload.data.TOKEN;
pwa.state.data.headers.xtribe = auth.data.payload.data.tribeid;
pwa.state.data.headers.xworkon = auth.data.payload.data.tribeid;
// Save local authentification uuid/token info user
pwa.state.data.login.user = auth.data.payload.data;
//request a refresh after a login
pwa.state.data.ctx.refreshstorage = true;
pwa.state.save();
//alert( 'pwa.state.save() fait avec uuid' + pwa.state.data.headers.xpaganid )
console.groupEnd();
return true;
} catch ( err ) {
if( err.response ) { console.log( "resp", err.response.data ) }
if( err.request ) { console.log( "req", err.request.data ) }
console.log( 'erreur de login reinit de rememberMe', err )
pwa.state.data.login.rememberMe = {};
document.querySelector( "#signin p.msginfo" )
.innerHTML = document.querySelector( "#signin [data-msgko]" )
.getAttribute( 'data-msgko' );
console.groupEnd();
return false;
}
};
pwa.auth.logout = function () {
console.log( "remove ", pwa.state.data.ctx.website );
localStorage.removeItem( pwa.state.data.ctx.website );
window.location.href = "/";
}
pwa.auth.login = async function () {
/*
Check login/psw
see auth.mustache & data_auth_lg.json for parameters
Context info used:
#signin p.msginfo contain message interaction with user
#signin data-msgok data-msgko
#signin button[data-routeto] is a redirection if authentification is successful
*/
document.querySelector( '#signin p.msginfo' )
.innerHTML = "";
const data = {
LOGIN: document.querySelector( "#signin input[name='login']" )
.value,
PASSWORD: document.querySelector( "#signin input[name='password']" )
.value
}
console.log( 'check password', Checkjson.test.password( "", data.PASSWORD ) )
if( data.LOGIN.length < 4 || !Checkjson.test.password( "", data.PASSWORD ) ) {
/*$("#loginpart p.msginfo")
.html("")
.fadeOut(2000)*/
document.querySelector( '#signin p.msginfo' )
.innerHTML = document.querySelector( '#signin [data-msgko]' )
.getAttribute( 'data-msgko' );
} else {
if( document.querySelector( "[name='rememberme']" )
.checked ) {
pwa.state.data.login.rememberMe = data;
}
if( await pwa.auth.authentification( data ) ) {
console.log( 'Authentification VALIDE' )
document.querySelector( '#signin p.msginfo' )
.innerHTML = document.querySelector( "#signin [data-msgok]" )
.getAttribute( 'data-msgok' );
//state l'état isAuthenticated et check la route
pwa.state.data.login.isAuthenticated = true;
pwa.state.save();
console.log( pwa.state.data.login )
console.log( 'Auth ok route to ', document.querySelector( '#signin button[data-routeto]' )
.getAttribute( 'data-routeto' ) );
pwa.auth.route( document.querySelector( '#signin button[data-routeto]' )
.getAttribute( 'data-routeto' ) );
}
}
};
pwa.auth.register = async function ( event ) {
event.preventDefault();
// gérer la cration du user
}
pwa.auth.forgetpsw = async function ( event ) {
event.preventDefault();
const tribeid = $( ".loginregister" )
.getAttribute( "data-tribeid" );
const email = $( '.forgetpsw .email' )
.val();
console.log( `Reinit email: ${email} for tribeid: ${tribeid}` )
try {
console.log( `https://${pwa.state.data.ctx.urlbackoffice }/users/getlinkwithoutpsw/${email}` )
const reinit = await axios.get( `https://${pwa.state.data.ctx.urlbackoffice }/users/getlinkwithoutpsw/${email}`, {
headers: pwa.state.data.headers
} )
$( "#forgetpswpart p.msginfo" )
.html( "Regardez votre boite email" );
return true;
} catch ( er ) {
console.log( "Pb d'accès au back check apiamaildigit" )
return false;
}
};

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,184 @@
/*
This module have to be independant of any external package
it is shared between back and front and is usefull
to apply common check in front before sending it in back
can be include in project with
<script src="https://apiback.maildigit.fr/js/Checkjson.js"></script>
or with const Checkjson = require('../public/js/Checkjson.js')
*/
// --##
const Checkjson = {};
// each Checkjson.test. return true or false
Checkjson.test = {};
Checkjson.test.emailadress = ( ctx, email ) => {
const regExp = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return regExp.test( email );
};
/*
* @emaillist = "email1,email2, email3"
* it check if each eamil separate by , are correct
*/
Checkjson.test.emailadresslist = ( ctx, emaillist ) => {
//console.log(emaillist.split(','))
if( emaillist.length > 0 ) {
const emails = emaillist.split( ',' );
for( var i in emails ) {
//console.log(emails[i])
if( !Checkjson.test.emailadress( "", emails[ i ].trim() ) ) {
return false
}
}
};
return true;
};
Checkjson.test.password = ( ctx, pwd ) => {
const regExp = new RegExp(
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&.])[A-Za-z\d$@$!%*?&.{}:|\s]{8,}/
);
return regExp.test( pwd );
};
Checkjson.test.required = ( ctx, val ) =>
val != null && val != 'undefined' && val.length > 0;
Checkjson.test.isNumber = ( ctx, n ) => typeof n === 'number';
Checkjson.test.isInt = ( ctx, n ) => n != '' && !isNaN( n ) && Math.round( n ) == n;
Checkjson.test.isFloat = ( ctx, n ) => n != '' && !isNaN( n ) && Math.round( n ) != n;
Checkjson.test.unique = ( ctx, val ) => {
if( ctx.list[ ctx.currentfield ] ) {
return !ctx.list[ ctx.currentfield ].includes( val );
} else {
console.log( 'ERR no list for field:' + ctx.currentfield );
return false;
}
};
Checkjson.test.isDateDay = ( ctx, dateDay ) => true;
/* Checkjson.test.filterInvalidInArray = (array, validate) =>
array ? array.filter(el => !validate(el)) : true;
// return true when every elements is valid
*/
Checkjson.test.postalCode = ( ctx, postalCode ) => {
if( postalCode.length == 0 ) return true;
const regExp = new RegExp( /(^\d{5}$)|(^\d{5}-\d{4}$)/ );
return regExp.test( postalCode );
};
/**
* PHONE
*/
Checkjson.test.phoneNumber = ( ctx, phoneNumber ) => {
if( phoneNumber.length == 0 ) return true;
phoneNumber = phoneNumber.trim()
.replace( /[- .]/g, '' )
//french number
const regExpfr = new RegExp( /^0[1-9][0-9]{9}$/ );
const regExpInternational = new RegExp( /^\+*(\d{3})*[0-9,\-]{8,}/ );
return regExpfr.test( phoneNumber ) || regExpInternational.test( phoneNumber );
};
/*
* @phonelist = "phone1,phone2,phone3"
* it check if each phone separate by , are correct
*/
Checkjson.test.phoneNumberlist = ( ctx, phonelist ) => {
//console.log(emaillist.split(','))
if( phonelist.length > 0 ) {
const phones = phonelist.split( ',' );
for( var i in phones ) {
//console.log(emails[i])
if( !Checkjson.test.phoneNumber( "", phones[ i ].trim() ) ) {
return false
}
}
};
return true;
};
// Checkjson.normalize take a correct data then reformat it to harmonise it
Checkjson.normalize = {};
Checkjson.normalize.phoneNumber = ( ctx, phone ) => {
phone = phone.trim()
.replace( /[- .]/g, '' );
if( Checkjson.test.phoneNumber( '', phone ) && phone.length == 10 && phone[ 0 ] == "0" ) {
phone = '+33 ' + phone.substring( 1 );
}
return phone;
}
Checkjson.normalize.upperCase = ( ctx, txt ) => txt.toUpperCase();
Checkjson.normalize.lowerCase = ( ctx, txt ) => txt.toLowerCase();
// fixe 10 position et complete par des 0 devant
Checkjson.normalize.zfill10 = ( ctx, num ) => {
let s = num + '';
while( s.length < 10 ) s = '0' + s;
return s;
};
/*let tt = "+33 1 02.03 04 05";
console.log(Checkjson.test.phoneNumber('', tt))
console.log(Checkjson.normalize.phoneNumber('', tt))
*/
Checkjson.evaluate = ( contexte, referential, data ) => {
/*
* contexte object {} with full info for evaluation
* file referential path to get object to apply
* data related to object
- return {validefor =[keyword of error] if empty no error,
clean data eventually reformated
updateDatabase}
*/
console.log( 'contexte', contexte );
console.log( 'referentiel', referential );
console.log( 'data', data );
const invalidefor = [];
const objectdef = {};
const listfield = referential.map( ch => {
objectdef[ ch.idfield ] = ch;
return ch.idfield;
} );
Object.keys( data )
.forEach( field => {
if( !listfield.includes( field ) ) {
// some data can be inside an object with no control at all
// they are used for process only
// i leave it in case it will become a non sens
// invalidefor.push('ERRFIELD unknown of referentials ' + field);
} else {
if( objectdef[ field ].check ) {
// check data with rule list in check
objectdef[ field ].Checkjson.forEach( ctrl => {
console.log( 'ctrl', ctrl );
contexte.currentfield = field;
if( !Checkjson.test[ ctrl ] ) {
invalidefor.push( 'ERR check function does not exist :' + ctrl + '___' + field )
} else {
if( !Checkjson.test[ ctrl ]( contexte, data[ field ] ) )
invalidefor.push( 'ERR' + ctrl + '___' + field );
}
} );
}
if( objectdef[ field ].nouserupdate ) {
// check if user can modify this information
console.log(
'evaluation :' + field + ' -- ' + objectdef[ field ].nouserupdate,
eval( objectdef[ field ].nouserupdate )
);
const evalright = eval( objectdef[ field ].nouserupdate );
objectdef[ field ].nouserupdate = evalright;
}
}
} );
console.log( {
invalidefor,
data
} );
return {
invalidefor,
data
};
};
if( typeof module !== 'undefined' ) module.exports = Checkjson;

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,150 @@
/*
After state.js / auth.js and all external js lib
Load
*/
var pwa = pwa || {};
pwa.main = pwa.main || {};
pwa.main.tpldata = pwa.main.tpldata || {};
pwa.main.tpl = pwa.main.tpl || {};
pwa.main.tpldata = pwa.main.tpldata || {};
pwa.main.ref = pwa.main.ref || {};
pwa.main.tpl.appsidebarmenu = 'static/components/appmesa/appsidebarmenu.mustache';
pwa.main.tpl.apptopbarmenu = 'static/components/appmesa/apptopbarmenu.mustache';
pwa.main.tpldata.sidebar = `static/components/appmesa/data_sidebar`;
pwa.main.tpldata.topbar = `static/components/appmesa/data_topbar`;
pwa.main.tpldata.topbarLogin = `static/components/appmesa/data_topbarLogin`;
pwa.main.init = () => {
const isempty = ( obj ) => {
return obj && Object.keys( obj )
.length === 0 && obj.constructor === Object
}
// Load public env tpl & tpldata
//Manage action depending of html file currently show
const currenthtml = location.pathname.split( '/' )
.at( -1 );
console.groupCollapsed( `pwa.main.init for ${currenthtml} html page` );
if( currenthtml.includes( 'app_' ) ) {
pwa.main.loadmenu()
}
// To manage if authenticated or not in a simple way
/*
if( pwa.state.data.login.isAuthenticated ) {
//authenticated
// identity inside pwa.state.login.user
}else{
//anonymous
// can check if the url is relevant with isAuthenticated
//route to app if exist data-routo into a signin
//pwa.auth.route( document.querySelector( '#signin button[data-routeto]' ).getAttribute( 'data-routeto' ) );
// add and load dynamicaly the gui.js plugin if user that request it has access
}
*/
console.groupEnd();
};
pwa.main.loadmenu = async () => {
console.log( 'pwa.main.loadmenu running' );
console.log( 'Status of pwa.state.data.login.isAuthenticated =', pwa.state.data.login.isAuthenticated );
let datasidebar, datatopbar;
/* Build datasidebar and datatopbar depending of list of module allowed by user in his ACCESSRIGHTS profil.
app[`${pwa.state.data.ctx.tribeid}:${pwa.state.data.ctx.website}`].js;
*/
//console.log( 'List of tpldata', pwa.main.tpldata )
//console.log( 'List of tpl', pwa.main.tpl )
console.log( `run pwa.state.loadfile with pwa.state.data.ctx.refreshstorage = ${pwa.state.data.ctx.refreshstorage} if true=> refresh anyway, if false refresh only if dest.name does not exist` );
await pwa.state.loadfile( pwa.main.tpl, 'tpl' );
await pwa.state.loadfile( pwa.main.tpldata, 'tpldata' );
datasidebar = pwa.state.data.tpldata.sidebar;
//any tpldata containing sidebar in pwa.state.data.tpldata is add to sbgroupmenu to be available
Object.keys( pwa.state.data.tpldata )
.filter( m => ( m != 'sidebar' && m.includes( 'sidebar' ) ) )
.some( k => {
datasidebar.sbgroupmenu.push( pwa.state.data.tpldata[ k ] )
} );
//merge les menu topbar
datatopbar = pwa.state.data.tpldata.topbar;
if( pwa.state.data.login.isAuthenticated ) {
// update user information if needed
datatopbar.name = pwa.state.data.login.user.LOGIN;
datatopbar.avatarimg = pwa.state.data.login.user.AVATARIMG;
delete pwa.state.data.tpldata.topbarLogin;
pwa.state.save();
}
datatopbar.menuprofil = [];
Object.keys( pwa.state.data.tpldata )
.filter( m => ( m != 'topbar' && m.includes( 'topbar' ) ) )
.some( k => {
datatopbar.menuprofil.push( pwa.state.data.tpldata[ k ] )
} );
if( pwa.state.data.tpl.appsidebarmenu ) {
document.querySelector( "#sidebar" )
.innerHTML = Mustache.render( pwa.state.data.tpl.appsidebarmenu, datasidebar )
document.querySelector( "#navbar" )
.innerHTML = Mustache.render( pwa.state.data.tpl.apptopbarmenu, datatopbar )
//active les icones svg de feather
feather.replace();
//active scroll presentation + sidebar animation
pwa.main.simplebar();
pwa.main.clickactive();
};
};
//////////////////////////////////////////////////////
// simplebar
//////////////////////////////////////////////////////
pwa.main.simplebar = () => {
const simpleBarElement = document.getElementsByClassName( "js-simplebar" )[ 0 ];
if( simpleBarElement ) {
/* Initialize simplebar */
new SimpleBar( document.getElementsByClassName( "js-simplebar" )[ 0 ] )
const sidebarElement = document.getElementsByClassName( "sidebar" )[ 0 ];
const sidebarToggleElement = document.getElementsByClassName( "sidebar-toggle" )[ 0 ];
sidebarToggleElement.addEventListener( "click", () => {
sidebarElement.classList.toggle( "collapsed" );
sidebarElement.addEventListener( "transitionend", () => {
window.dispatchEvent( new Event( "resize" ) );
} );
} );
}
}
/////////////////////////////////////////////////////////
// manage click effect
////////////////////////////////////////////////////////
pwa.main.clickactive = () => {
const cleanactive = () => {
const el = document.querySelectorAll( '.sidebar-item' )
for( var i = 0; i < el.length; i++ ) {
//console.log( 'clean', el[ i ].classList )
el[ i ].classList.remove( 'active' );
}
}
document.addEventListener( "click", ( e ) => {
console.log( 'click', e );
if( e.target.classList.contains( 'sidebar-link' ) ) {
cleanactive();
e.target.closest( '.sidebar-item' )
.classList.add( 'active' );
// remonte au menu au dessus si existe
e.target.closest( '.sidebar-item' )
.closest( '.sidebar-item' )
.classList.add( 'active' );
}
} );
// If enter run the research
document.getElementById( 'globalsearch' )
.addEventListener( 'keypress', ( e ) => {
if( e.keyCode == 13 ) {
pwa.search.req( 'globalsearch' );
e.preventDefault();
}
} )
};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,28 @@
"use strict";
var pwa = pwa || {};
/*
Manage notification
Get notification after tomenu was load
from /components/notification
____________________
*/
//--##
pwa.notification = {};
pwa.notification.update = () => {
console.log( 'get notification update for a user' );
axios.get( `https://${pwa.state.data.ctx.urlbackoffice}/notifications/user`, { headers: pwa.state.data.headers } )
.then( rep => {
console.log( "list des notifs", rep.data.payload.data )
rep.data.payload.data.number = rep.data.payload.data.notifs.length;
document.getElementById( "topbarmenuright" )
.innerHTML = Mustache.render( pwa.state.data.tpl.notiflist, rep.data.payload.data ) + document.getElementById( "topbarmenuright" )
.innerHTML;
} )
.catch( err => {
console.log( `Err pwa.notification.update data for user into header ${pwa.state.data.headers}`, err );
} );
};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,261 @@
"use strict";
var pwa = pwa || {};
/*
FROM ndda/plugins/maildigitcreator/appjs/state.js
Manage state of the webapp
author: Phil Colzy - yzlocp@gmail.com
____________________________
pwa.state.save(): save in localstorage pwa.state.data avec le Nom du projet
____________________________
pwa.state.update(): update localstorage data from referential version
____________________________
pwa.state.ready(callback): await DOM loaded before running the callback
____________________________
pwa.state.refresh(): check if newversion of webapp to refresh page for dev purpose (do not use to refresh data)
____________________________
pwa.state.route(); check url and reroute it to function(urlparameter) or hide show part into a onepage website.
____________________________
pwa.state.loadfile({key:url},'dest') store in pwa.state.data.dest.key= file from url await all key to store result
___________________________
pwa.state.confdev() if ENV is dev then change urlbase for axios to looking for relevant file and refresh at a frequency pwa.state.refresh()
*/
//--##
pwa.state = {};
pwa.state.refresh = () => {
//console.warn(`Lance le refresh de${pwa.state.env.page}`)
//console.warn( 'ggg', pwa.state.data.ctx.urlbase )
const currenthtml = location.pathname.split( '/' )
.at( -1 )
.replace( '.html', '.json' );
//console.log( currenthtml )
axios.get( ` ${pwa.state.data.ctx.urlbase}/static/lastchange/${currenthtml}` )
.then(
data => {
//console.log( data.data.time, pwa.state.data.ctx.version )
if( data.data.time > pwa.state.data.ctx.version ) {
//console.log( "reload la page pour cause de lastchange detecté" );
pwa.state.data.ctx.version = data.data.time;
pwa.state.data.ctx.refreshstorage = true;
pwa.state.save();
location.reload();
} else {
//console.log( 'nothing change' )
}
},
error => {
console.log( error );
}
);
};
pwa.state.ready = callback => {
// Equivalent of jquery Document.ready()
// in case the document is already rendered
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();
} );
};
pwa.state.route = async () => {
/* Allow to create dynamic content
?action=pwa object&id=&hh& => pwa.action("?action=pwa object&id=&hh&")
ex: ?action=test.toto&id=1&t=123
Each function that can be called have to start with
if (e[1]=="?"){
const urlpar = new URLSearchParams( loc.search );
Then set param with urlpar.get('variable name')
}
OR ?pagemd=name used into .html (div)
Then it hide all <div class="pagemd" and show the one with <div id="page"+name
*/
console.groupCollapsed( `pwa.state.route with window.location` );
console.log( 'List of pwa available ', Object.keys( pwa ) );
if( !pwa.auth ) {
console.log( 'Warning, no auth.js, not a pb if no authentification need, if not check js order to be sur auth.js load before state.js' )
} else {
// check if still authenticated
if( pwa.state.data.login.isAuthenticated ) {
pwa.state.data.login.isAuthenticated = await pwa.auth.isAuthenticate();
}
//check if need authentification to show this page
if( pwa.state.data.ctx.pageneedauthentification && !pwa.state.data.login.isAuthenticated ) {
console.log( 'reload page cause not auth and page require an auth' )
window.location = `${pwa.state.data.ctx.pageredirectforauthentification}_${pwa.state.data.ctx.lang}.html`;
}
}
const loc = window.location;
if( loc.search ) {
console.log( Object.keys( pwa ) )
const urlpar = new URLSearchParams( loc.search );
if( urlpar.get( 'action' ) ) {
const act = 'pwa.' + urlpar.get( 'action' ) + '("' + loc.search + '")';
try {
eval( act );
console.log( 'Specific action request to pwa.' + act )
} catch ( err ) {
console.log( err )
console.error( `You request ${act}, this action does not exist ` );
alert( `Sorry but you have no access to ${act}, ask your admin` );
}
}
let pgid = "pageindex"
if( urlpar.get( 'pagemd' ) ) {
pgid = "page" + urlpar.get( 'pagemd' )
}
//route to page content
Array.from( document.getElementsByClassName( "pagemd" ) )
.forEach( e => {
console.log( "detect pagemd", e.getAttribute( 'data-url' ) );
e.classList.add( "d-none" );
} );
if( document.getElementById( pgid ) ) {
document.getElementById( pgid )
.classList.remove( 'd-none' );
}
}
console.groupEnd();
// If pwa.main exist then start pwa.main.init();
if( pwa.main ) pwa.main.init();
}
pwa.state.loadfile = async ( list, dest ) => {
// load external file if flag pwa.state.data.ctx.refreshstorage is true from pwa.state.refresh();
//from list = {name:url} request are done with ctx.urlbase/url and store in localstorage pwa.state.data[dest][name]=data
// if dest=='js' then it eval the js and store origin in pwa.state.data.js={name:url}
//For at true refreshstorage if destination pwa.state.dest does not exist
//console.log( 'list', list )
//console.log( 'pwa.state.data.ctx.refreshstorage', pwa.state.data.ctx.refreshstorage )
if( pwa.state.data.ctx.refreshstorage || !pwa.state.data[ dest ] || Object.keys( pwa.state.data[ dest ] )
.length == 0 ) {
if( !pwa.state.data[ dest ] ) pwa.state.data[ dest ] = {};
try {
let reqname = [];
let reqload = [];
for( const [ k, v ] of Object.entries( list ) ) {
if( !pwa.state.data[ dest ][ k ] || pwa.state.data.ctx.refreshstorage ) {
// if still not exist or refresstorage is set to true then add to load
//@TODO check it works well on production
reqname.push( k );
reqload.push( v );
}
};
//console.log( pwa.state.data.ctx.urlbase, reqload )
let resload = await Promise.all( reqload.map( r => {
if( dest == 'tpldata' ) r = `${r}_${pwa.state.data.ctx.lang}.json`;
return axios.get( `${pwa.state.data.ctx.urlbase}/${r}`, { headers: pwa.state.data.headers } )
} ) );
resload.forEach( ( d, i ) => {
pwa.state.data[ dest ][ reqname[ i ] ] = d.data;
pwa.state.save();
} )
} catch ( err ) {
console.error( 'FATAL ERROR check that list exist remove if not', list, err.message )
}
}
};
pwa.state.save = function () {
localStorage.setItem( pwa.state.data.ctx.website, JSON.stringify( pwa.state.data ) );
};
pwa.state.update = async function () {
const domhtml = document.querySelector( "html" );
const ctx = {
tribeid: domhtml.getAttribute( 'data-tribeid' ),
website: domhtml.getAttribute( "data-website" ),
nametpl: domhtml.getAttribute( "data-nametpl" ),
pagename: domhtml.getAttribute( "data-pagename" ),
urlbackoffice: domhtml.getAttribute( "data-urlbackoffice" ),
pageneedauthentification: true,
pageredirectforauthentification: "",
lang: domhtml.getAttribute( "lang" ),
env: domhtml.getAttribute( "data-env" ),
version: domhtml.getAttribute( "data-version" ),
refreshstorage: false
}
if( !domhtml.getAttribute( 'data-pageneedauthentification' ) || domhtml.getAttribute( 'data-pageneedauthentification' ) == 'false' ) {
ctx.pageneedauthentification = false;
}
if( domhtml.getAttribute( 'data-pageforauthentification' ) ) {
ctx.pageforauthentification = domhtml.getAttribute( 'data-pageforauthentification' );
}
console.groupCollapsed( `update pwa.state with html attribut or from localstorage into ${ctx.website}` );
console.log( 'html context:', ctx );
if( localStorage.getItem( ctx.website ) ) {
pwa.state.data = JSON.parse( localStorage.getItem( ctx.website ) );
//alert( 'recupere pwa.state.data xpaganid:' + pwa.state.data.headers.xpaganid )
}
if( !( pwa.state.data && pwa.state.data.ctx.tribeid == ctx.tribeid && pwa.state.data.ctx.website == ctx.website ) ) {
console.log( " reinitialise localstorage cause work on a different project or first access" );
delete pwa.state.data;
localStorage.removeItem( ctx.website )
}
/*
if( pwa.state.data && statejson.data.app.version && ( parseInt( pwa.state.data.app.version ) < parseInt( statejson.data.app.version ) ) ) {
// le numero de version en mémoire est < au numero disponible sur le serveur
// force un logout pour reinitialiser les menus
delete pwa.state.data;
localStorage.removeItem( pwa.PROJET )
}
*/
if( !pwa.state.data ) {
// No localstorage available et one by default
pwa.state.data = {
ctx,
login: {
isAuthenticated: false,
user: {},
rememberMe: {}
},
headers: {
'xauth': '1',
'xpaganid': '1',
'xtribe': ctx.tribeid,
'xlang': ctx.lang,
'xworkon': ctx.tribeid,
'xapp': `${ctx.tribeid}:${ctx.website}`
}
}
console.log( 'load new state.data', pwa.state.data )
}
// Check if external component need to be load
const app = `${pwa.state.data.ctx.tribeid}:${pwa.state.data.ctx.website}`;
if( pwa.state.data.login.isAuthenticated &&
pwa.state.data.login.user.ACCESSRIGHTS.app[ app ] &&
pwa.state.data.login.user.ACCESSRIGHTS.app[ app ].js
) {
console.log( 'tttt', pwa.state.data.login.isAuthenticated, pwa.state.data.login.user.ACCESSRIGHTS.app[ app ].js )
pwa.state.data.login.user.ACCESSRIGHTS.app[ app ].js.some( ( u ) => {
console.log( `load from user ACCESSRIGHTS app[${pwa.state.data.ctx.tribeid}:${pwa.state.data.ctx.website}].js : ${u}` )
const script = document.createElement( 'script' );
script.src = u;
script.async = false;
document.body.appendChild( script );
} );
}
//Check dev to set parameter to simplify dev app
//check in confdev version and set pwa.state.data.ctx.refreshstorage at true if new version
pwa.state.confdev();
console.groupEnd();
pwa.state.route();
pwa.state.save();
};
pwa.state.confdev = () => {
if( pwa.state.data.ctx.env == 'dev' ) {
pwa.state.data.ctx.urlbase = `/space/${pwa.state.data.ctx.tribeid}/${pwa.state.data.ctx.website}/dist`;
// check each 3 sec if new version to reload
setInterval( "pwa.state.refresh()", 3000 );
} else {
//pwa.state.axios = axios.create();
pwa.state.data.ctx.urlbase = "/";
// check and refresh if new version only one time
pwa.state.refresh();
}
}
// Refresh browser state if exist else get pwa.state defaults
pwa.state.ready( pwa.state.update );