2023-01-22 09:53:09 +00:00
const bcrypt = require ( 'bcrypt' ) ;
const fs = require ( 'fs-extra' ) ;
const jsonfile = require ( 'jsonfile' ) ;
const glob = require ( 'glob' ) ;
const moment = require ( 'moment' ) ;
const jwt = require ( 'jwt-simple' ) ;
const UUID = require ( 'uuid' ) ;
const Outputs = require ( './Outputs.js' ) ;
const config = require ( '../tribes/townconf.js' ) ;
2023-02-10 10:48:45 +00:00
const checkdata = require ( ` ../nationchains/socialworld/contracts/checkdata.js ` ) ;
2023-01-22 09:53:09 +00:00
/ *
Gestion des utilisateurs connecte
/ t r i b e s / t r i b e i d / u s e r s /
UUID . json
/ s e a r c h i n d e x / i n d e x T O K E N = { T O K E N : U U I D }
to check authentification
indexLOGIN = { LOGIN : UUID }
to check if LOGIN exist
Used for referntial :
To update
Global : datashared / referentials / dataManagement / object / users . json
Local : data / tribe / * $ { header . workOn } / referentials / dataManagement / object / users . json
To use after a server rerun
data / tribe / * $ { header . workOn } / referentials / $ { header . langue } / object / users . json
Faire comme contact charger les index au lancement
et changer la logique de user / id / profil o
On initialise les objets au lancement du serveur
this . uids [ u . UUID ] = [ u . LOGIN , u . EMAIL , u . password , u . profil , u . TOKEN ] ;
this . logins [ u . LOGIN ] = u . UUID ;
this . tokens [ u . UUID ] = u . TOKEN ;
on stocke / domain / tribeid / users / logins . json et / uids . json
on stocke / domain / tribeids . json et tokkens . json
On retourne l ' objet { tribeids : [ list tribeid ] , tokens : { UUID : TOKEN } }
* /
const Pagans = { } ;
Pagans . init = tribeids => {
console . group ( 'init Pagans logins, tokens ...' ) ;
// store globaly tokens
const tokens = { } ;
const emailsglob = { } ;
const loginsglob = { } ;
// For each tribeid create series of indexes
2023-02-21 20:51:11 +00:00
//logger.info(tribeids);
2023-01-22 09:53:09 +00:00
tribeids . forEach ( tribeid => {
// Reset for each domain
const uids = { } ;
const logins = { } ;
const emails = { } ;
//check folder exist
/*if( !fs.existsSync( `${config.tribes}/ $ { tribeid } / users ` ) ) {
fs . mkdirSync ( ` ${ config . tribes } / ${ tribeid } /users ` )
}
if ( ! fs . existsSync ( ` ${ config . tribes } / ${ tribeid } /users/searchindex ` ) ) {
fs . mkdirSync ( ` ${ config . tribes } / ${ tribeid } /users/searchindex ` )
} * /
glob . sync ( ` ${ config . tribes } / ${ tribeid } /users/*.json ` )
. forEach ( file => {
2023-02-21 20:51:11 +00:00
//logger.info( file );
2023-01-22 09:53:09 +00:00
const u = fs . readJsonSync ( file , 'utf-8' ) ;
if ( ! u . TOKEN ) {
u . TOKEN = '' ;
}
2023-02-21 20:51:11 +00:00
//logger.info( u )
2023-01-22 09:53:09 +00:00
uids [ u . UUID ] = [ u . LOGIN , u . EMAIL , u . PASSWORD , u . ACCESSRIGHTS , u . TOKEN ] ;
logins [ u . LOGIN ] = u . UUID ;
loginsglob [ u . LOGIN ] = tribeid ;
// On ne charge que les TOKEN valide
let decodedTOKEN = { } ;
if ( u . TOKEN != '' ) {
try {
decodedTOKEN = jwt . decode ( u . TOKEN , config . jwtSecret ) ;
2023-02-21 20:51:11 +00:00
//logger.info( 'decodeTOKEN', decodedTOKEN )
2023-01-22 09:53:09 +00:00
if ( moment ( decodedTOKEN . expiration ) > moment ( ) ) {
tokens [ u . UUID ] = { TOKEN : u . TOKEN , ACCESSRIGHTS : u . ACCESSRIGHTS } ;
2023-02-21 20:51:11 +00:00
//logger.info( `add token valid for ${u.UUID}:`, tokens[ u.UUID ] )
2023-01-22 09:53:09 +00:00
}
} catch ( err ) {
2023-02-21 20:51:11 +00:00
logger . info ( 'pb de TOKEN impossible a decoder' + u . TOKEN , err ) ;
2023-01-22 09:53:09 +00:00
}
}
if ( u . EMAIL ) {
emails [ u . EMAIL ] = u . UUID ;
emailsglob [ u . EMAIL ] = tribeid ;
}
} ) ;
// UIDS INDEX BY DOMAIN ={UUID:[LOGIN,EMAIL,psw,accessRight,TOKEN]}
fs . outputJson ( ` ${ config . tribes } / ${ tribeid } /users/searchindex/uids.json ` , uids , {
spaces : 2
} , err => {
if ( err ) throw err ;
} ) ;
// LOGINS INDEX BY DOMAIN ={LOGIN:UUID}
fs . outputJson ( ` ${ config . tribes } / ${ tribeid } /users/searchindex/logins.json ` , logins , {
spaces : 2
} , err => {
if ( err ) throw err ;
} ) ;
// EMAILS INDEX BY DOMAIN ={EMAIL:UUID}
fs . outputJson ( ` ${ config . tribes } / ${ tribeid } /users/searchindex/emails.json ` , emails , {
spaces : 2
} , err => {
if ( err ) throw err ;
} ) ;
} ) ;
// EMAILS et appartenance domain
fs . outputJson ( ` ${ config . tmp } /emailsglob.json ` , emailsglob , {
spaces : 2
} , err => {
if ( err ) throw err ;
} ) ;
// logins et appartenance domain (permet de retrouver tribeid pour un LOGIN)
fs . outputJson ( ` ${ config . tmp } /loginsglob.json ` , loginsglob , {
spaces : 2
} , err => {
if ( err ) throw err ;
} ) ;
// TOKENS GLOBAL INDEX Centralise tous les TOKEN pour plus de rapidité
// {UUID:TOKEN}
fs . outputJson ( ` ${ config . tmp } /tokens.json ` , tokens , {
spaces : 2
} , err => {
if ( err ) throw err ;
} ) ;
console . groupEnd ( ) ;
return { tokens } ;
} ;
/ * *
* Update indexes : logins , uids and tokens
* @ param { object } user User object
* @ param { string } tribeid - The client identifier
* @ rm { boolean } false => update , true => remove
* /
Pagans . updateDatabase = ( user , tribeid , rm = false ) => {
console . group ( ` Pagans.updateDatabase for ${ tribeid } with user ${ user . LOGIN } ` )
console . assert ( config . loglevel == "quiet" , 'user' , user ) ;
const loginsIndex = ` ${ config . tribes } / ${ tribeid } /users/searchindex/logins.json ` ;
jsonfile . readFile ( loginsIndex , function ( err , logins ) {
console . assert ( config . loglevel == "quiet" , 'logins' , logins ) ;
try {
if ( rm ) {
delete logins [ user . LOGIN ] ;
} else {
logins [ user . LOGIN ] = user . UUID ;
}
jsonfile . writeFile ( loginsIndex , logins , {
spaces : 2
} , err => {
2023-02-21 20:51:11 +00:00
if ( err ) logger . info ( err ) ;
2023-01-22 09:53:09 +00:00
} ) ;
} catch ( err ) {
2023-02-21 20:51:11 +00:00
logger . info ( 'Gros pb de mise à jour Pagans.updateDatabase conflit des logins' ) ;
2023-01-22 09:53:09 +00:00
}
} ) ;
const uidsIndex = ` ${ config . tribes } / ${ tribeid } /users/searchindex/uids.json ` ;
jsonfile . readFile ( uidsIndex , function ( err , uids ) {
try {
if ( rm ) {
delete uids [ user . UUID ] ;
} else {
uids [ user . UUID ] = [
user . LOGIN ,
user . EMAIL ,
user . PASSWORD ,
user . ACCESSRIGHTS ,
user . TOKEN
] ;
}
jsonfile . writeFile ( uidsIndex , uids , {
spaces : 2
} , err => {
2023-02-21 20:51:11 +00:00
if ( err ) logger . info ( err ) ;
2023-01-22 09:53:09 +00:00
} ) ;
} catch ( err ) {
2023-02-21 20:51:11 +00:00
logger . info ( 'Gros pb de mise à jour Pagans.updateDatabase conflit des uids si ce reproduit passer en mode sync bloquant' ) ;
2023-01-22 09:53:09 +00:00
}
} ) ;
const emailsIndex = ` ${ config . tribes } / ${ tribeid } /users/searchindex/emails.json ` ;
jsonfile . readFile ( emailsIndex , function ( err , emails ) {
console . assert ( config . loglevel == "quiet" , 'emailss' , emails ) ;
try {
if ( rm ) {
delete emails [ user . EMAIL ] ;
} else {
emails [ user . EMAIL ] = user . UUID ;
}
jsonfile . writeFile ( emailsIndex , emails , {
spaces : 2
} , err => {
2023-02-21 20:51:11 +00:00
if ( err ) logger . info ( err ) ;
2023-01-22 09:53:09 +00:00
} ) ;
} catch ( err ) {
2023-02-21 20:51:11 +00:00
logger . info ( 'Gros pb de mise à jour Pagans.updateDatabase conflit des emails' ) ;
2023-01-22 09:53:09 +00:00
}
} ) ;
const tokensIndex = ` ${ config . tmp } /tokens.json ` ;
let tokens = { } ;
try {
tokens = jsonfile . readFileSync ( tokensIndex ) ;
} catch ( err ) {
2023-02-21 20:51:11 +00:00
logger . info ( 'tokens.json not available' )
2023-01-22 09:53:09 +00:00
}
// tokens[user.UUID] = user.TOKEN;
tokens [ user . UUID ] = { TOKEN : user . TOKEN , ACCESSRIGHTS : user . ACCESSRIGHTS } ;
jsonfile . writeFileSync ( tokensIndex , tokens , {
spaces : 2
} ) ;
/ *
jsonfile . readFile ( tokensIndex , function ( err , tokens ) {
tokens [ user . UUID ] = user . TOKEN ;
jsonfile . writeFile ( tokensIndex , tokens , { spaces : 2 } , err => {
2023-02-21 20:51:11 +00:00
if ( err ) logger . info ( err ) ;
2023-01-22 09:53:09 +00:00
} ) ;
} ) ; * /
console . groupEnd ( ) ;
} ;
/ * *
* Read the profil . json of an user
* @ param { [ type ] } UUID ID of the user
* @ param { [ type ] } tribeid tribeid
* @ return { Promise } - Return a promise resolved with user data or rejected with an error
* /
// A S U P P R I M E R utiliser getinfousers pour recuperer des indexs de users
// en créer d'autres si necessaire
Pagans . getUserlist = ( header , filter , field ) => {
console . group ( ` getUserlist filter with filter ${ filter } to get ${ field } ` ) ;
/ * c o n s t g e t u s e r = P a g a n s . g e t U s e r ( h e a d e r . x u u i d , h e a d e r . x t r i b e i d ) ;
if ( getuser . status != 200 )
return { status : getuser . status , data : getuser . payload } ;
const user = getuser . payload . data ;
2023-02-21 20:51:11 +00:00
// logger.info(user);
2023-01-22 09:53:09 +00:00
// check if update accessright allowed
// choose the level depending of ownby xuuid
let accessright = user . objectRights [ header . xtribeid ] . users [ 0 ] ;
if ( user . ownby . includes ( header . xtribeid ) ) {
accessright = user . objectRights [ header . xtribeid ] . users [ 1 ] ;
}
// Check update is possible at least user itself ownby itself
2023-02-21 20:51:11 +00:00
logger . info ( accessright ) ;
logger . info ( accessright & 4 ) ;
2023-01-22 09:53:09 +00:00
if ( ( accessright & 4 ) != 4 ) {
return {
status : 403 ,
data : { info : [ 'forbiddenAccess' ] , model : 'Pagans' }
} ;
}
* /
const Userlist = [ ] ;
glob . sync ( ` ${ config . tribes } / ${ header . xworkon } /users/*/profil.json ` )
. forEach ( f => {
const infouser = jsonfile . readFileSync ( f ) ;
// Ajouter filter et liste de field
if ( filter != 'all' ) {
// decode filter et test
}
const info = { } ;
field . split ( '______' )
. forEach ( k => {
if ( ! [ 'password' ] . includes ( k ) ) info [ k ] = infouser [ k ] ;
} ) ;
Userlist . push ( info ) ;
} ) ;
2023-02-21 20:51:11 +00:00
// logger.info('userlist', Userlist);
2023-01-22 09:53:09 +00:00
console . groupEnd ( ) ;
return {
status : 200 ,
data : {
data : Userlist
}
} ;
} ;
Pagans . getinfoPagans = ( tribeid , accessrights , listindex ) => {
const info = { }
const object = 'users' ;
const indexs = listindex . split ( '_' )
let access = true ;
indexs . forEach ( index => {
access = ! ( [ 'emails' , 'logins' , 'uids' ] . includes ( index ) && ! ( accessrights . data [ object ] && accessrights . data [ object ] . includes ( 'R' ) ) ) ;
if ( access && fs . existsSync ( ` ${ config . tribes } / ${ tribeid } / ${ object } /searchindex/ ${ index } .json ` ) ) {
info [ index ] = jsonfile . readFileSync ( ` ${ config . tribes } / ${ tribeid } / ${ object } /searchindex/ ${ index } .json ` )
}
} )
2023-02-21 20:51:11 +00:00
logger . info ( info )
2023-01-22 09:53:09 +00:00
return { status : 200 , data : { info : info } }
}
Pagans . getUser = ( UUID , tribeid , accessrights ) => {
console . assert ( config . loglevel == "quiet" , ` getUser on ${ UUID } for ${ tribeid } with ${ JSON . stringify ( accessrights ) } ` ) ;
if ( ! fs . existsSync ( ` ${ config . tribes } / ${ tribeid } /users/ ${ UUID } .json ` ) ) {
return {
status : 404 ,
data : {
info : [ 'useridNotfound' ] ,
model : 'Pagans' ,
render : {
UUID ,
tribeid
}
}
}
}
const user = jsonfile . readFileSync ( ` ${ config . tribes } / ${ tribeid } /users/ ${ UUID } .json ` ) ;
let access = true ;
2023-02-21 20:51:11 +00:00
//logger.info("test accessrights.data['users'].includes('R')", accessrights.data['users'].includes('R'))
2023-01-22 09:53:09 +00:00
console . assert ( config . loglevel == "quiet" , 'accessrights' , accessrights )
access = accessrights . users && ( accessrights . users . includes ( 'R' ) || ( accessrights . users . includes ( 'O' ) && user . OWNEDBY . includes ( UUID ) ) ) ;
if ( access ) {
return {
status : 200 ,
data : {
user : user ,
model : "User" ,
info : [ "Authorizedtogetuserinfo" ]
}
} ;
}
return {
status : 403 ,
data : {
info : [ 'Forbidden' ] ,
model : 'Pagans' ,
render : {
UUID ,
tribeid
}
}
} ;
} ;
Pagans . getUserIdFromEMAIL = ( tribeid , EMAIL ) => {
if ( ! checkdata . test . EMAIL ( EMAIL ) ) {
return {
status : 400 ,
data : {
info : [ 'ERREMAIL' ] ,
model : 'Pagans'
}
} ;
}
const emailsIndex = jsonfile . readFileSync ( ` ${ config . tribes } / ${ tribeid } /users/searchindex/emails.json ` ) ;
if ( ! emailsIndex . hasOwnProperty ( EMAIL ) ) {
return {
status : 404 ,
data : {
info : [ 'userEMAILNotfound' ] ,
model : 'Pagans'
}
} ;
}
return emailsIndex [ EMAIL ] ;
} ;
Pagans . updateUserpassword = ( UUID , header , data ) => {
const getUser = Pagans . getUser ( UUID , header . xtribeid , { users : 'W' } ) ;
if ( getUser . status == 200 ) {
const user = getUser . data . user ;
2023-02-21 20:51:11 +00:00
// logger.info('user exist', user);
2023-01-22 09:53:09 +00:00
const match = bcrypt . compareSync ( data . password , user . PASSWORD ) ;
if ( ! match ) {
return {
status : 401 ,
data : {
info : [ 'checkCredentials' ] ,
model : 'Pagans'
}
} ;
}
2023-02-21 20:51:11 +00:00
// logger.info('Credentials are matching!');
2023-01-22 09:53:09 +00:00
if ( checkdata . test . password ( { } , data . pswnew ) ) {
user . PASSWORD = bcrypt . hashSync ( data . pswnew , config . saltRounds ) ;
jsonfile . writeFileSync ( ` ${ config . tribes } / ${ header . xworkon } /users/ ${ UUID } .json ` , user , {
spaces : 2
} ) ;
Pagans . updateDatabase ( user , header . xworkon , false ) ;
return {
status : 200 ,
data : {
info : [ 'successfulUpdate' ] ,
model : 'Pagans'
}
} ;
} else {
return {
status : 401 ,
data : {
info : [ 'pswTooSimple' ] ,
model : 'Pagans'
}
} ;
}
}
} ;
Pagans . createUser = ( header , data ) => {
/ *
@ input data = { PUBKEY , EMAIL , LOGIN , UUID } check and create for header xworkon a user with generic password
* /
2023-02-21 20:51:11 +00:00
logger . info ( 'createUser on header.xworkon:' + header . xworkon + ' by user:' + header . xpaganid ) ;
2023-01-22 09:53:09 +00:00
console . assert ( config . loglevel == "quiet" , 'with data:' , data ) ;
const ref = jsonfile . readFileSync ( ` ${ config . tribes } / ${ header . xworkon } /referentials/ ${ header . xlang } /object/users.json ` ) ;
const logins = jsonfile . readFileSync ( ` ${ config . tribes } / ${ header . xworkon } /users/searchindex/logins.json ` ) ;
const LOGIN = Object . keys ( logins ) ;
console . assert ( config . loglevel == "quiet" , 'LOGIN list' , LOGIN ) ;
const emails = jsonfile . readFileSync ( ` ${ config . tribes } / ${ header . xworkon } /users/searchindex/emails.json ` ) ;
console . assert ( config . loglevel == "quiet" , 'emails' , emails ) ;
const EMAIL = Object . keys ( emails ) ;
console . assert ( config . loglevel == "quiet" , 'EMAIL list' , EMAIL ) ;
// list.UUID est forcement unique car on est en update et pas en create
if ( ! data . UUID ) data . UUID = UUID . v4 ( ) ;
// pour la logique de checkdata il faut passer le parametre
const check = checkdata . evaluate ( {
list : {
LOGIN ,
EMAIL ,
UUID : [ ]
}
} , ref , data ) ;
console . assert ( config . loglevel == "quiet" , 'check & clean data before update ' , check ) ;
if ( check . invalidefor . length > 0 ) {
return {
status : 403 ,
data : {
model : 'Pagans' ,
info : check . invalidefor
}
} ;
}
const clientConfig = jsonfile . readFileSync ( ` ${ config . tribes } / ${ header . xworkon } /clientconf.json ` ) ;
const user = check . data ;
user . DATE _CREATE = new Date ( )
. toISOString ( ) ;
user . PASSWORD = bcrypt . hashSync ( clientConfig . genericpsw , config . saltRounds ) ;
user . OWNBY = [ data . UUID ] ;
user . OBJECT = 'users' ;
// set le minimum de droit sur l'objet users dont il est le Owner
if ( data . ACCESSRIGHTS ) {
user . ACCESSRIGHTS = data . ACCESSRIGHTS
} else {
user . ACCESSRIGHTS = { app : { } , data : { } } ;
}
user . ACCESSRIGHTS . data [ header . xworkon ] = { users : "O" } ;
jsonfile . writeFileSync ( ` ${ config . tribes } / ${ header . xworkon } /users/ ${ user . UUID } .json ` , user , {
spaces : 2
} ) ;
Pagans . updateDatabase ( user , header . xworkon , false ) ;
return {
status : 200 ,
data : {
uuid : user . UUID ,
info : [ 'successfulCreate' ] ,
model : 'Pagans'
}
} ;
} ;
Pagans . updateUser = ( UUID , header , data ) => {
2023-02-21 20:51:11 +00:00
logger . info ( 'updateUser UUID:' + UUID + ' on header.xworkon:' + header . xworkon + ' by user' + header . xpaganid ) ;
// logger.info('header', header);
2023-01-22 09:53:09 +00:00
console . assert ( config . loglevel == "quiet" , 'with data' , data ) ;
const getuser = Pagans . getUser ( UUID , header . xworkon , { users : 'R' } ) ;
if ( getuser . status != 200 ) return {
status : getuser . status ,
data : getuser . data . user
} ;
const user = getuser . data . user ;
/ *
let userconnected = user ;
if ( UUID != header . xuuid ) {
// mean connected user want to change other user
const getuserconnected = Pagans . getUser ( header . xuuid , header . xtribeid ) ;
userconnected = getuserconnected . payload . data ;
}
2023-02-21 20:51:11 +00:00
logger . info ( 'user to update' , user ) ;
logger . info ( 'user connected that request update' , userconnected ) ;
2023-01-22 09:53:09 +00:00
// check if update accessright allowed
// choose the level depending of ownby xuuid
let accessright = userconnected . objectRights [ header . xworkon ] . users [ 0 ] ;
if ( user . ownby . includes ( header . xuuid ) ) {
accessright = userconnected . objectRights [ header . xworkon ] . users [ 1 ] ;
}
// Check update is possible at least user itself ownby itself
2023-02-21 20:51:11 +00:00
logger . info ( accessright ) ;
logger . info ( accessright & 2 ) ;
2023-01-22 09:53:09 +00:00
if ( ( accessright & 2 ) != 2 ) {
return {
status : 403 ,
data : { info : [ 'forbiddenAccess' ] , model : 'Pagans' }
} ;
}
* /
const ref = jsonfile . readFileSync ( ` ${ config . tribes } / ${ header . xworkon } /referentials/object/users_ ${
header . xlang
} . json ` );
const logins = jsonfile . readFileSync ( ` ${ config . tribes } / ${ header . xworkon } /users/searchindex/logins.json ` ) ;
const LOGIN = Object . keys ( logins )
. filter ( l => logins [ l ] != user . UUID ) ;
2023-02-21 20:51:11 +00:00
// logger.info( 'LOGIN list', LOGIN );
2023-01-22 09:53:09 +00:00
const emails = jsonfile . readFileSync ( ` ${ config . tribes } / ${ header . xworkon } /users/searchindex/emails.json ` ) ;
2023-02-21 20:51:11 +00:00
// logger.info( 'emails', emails );
2023-01-22 09:53:09 +00:00
const EMAIL = Object . keys ( emails )
. filter ( e => emails [ e ] != user . UUID ) ;
2023-02-21 20:51:11 +00:00
// logger.info( 'EMAIL list', EMAIL );
2023-01-22 09:53:09 +00:00
// list.UUID est forcement unique car on est en update et pas en create
// pour la logique de checkdata il faut passer le parametre
const check = checkdata . evaluate ( {
profil : user [ 'apps' + header . xworkon + 'profil' ] ,
list : {
LOGIN ,
EMAIL ,
UUID : [ ]
}
} , ref , data ) ;
if ( check . invalidefor . length > 0 ) {
return {
status : 403 ,
data : {
model : 'Pagans' ,
info : check . invalidefor ,
}
} ;
}
data = check . data ;
let saveuser = false ;
let updateDatabase = false ;
Object . keys ( data )
. forEach ( k => {
2023-02-21 20:51:11 +00:00
//logger.info( user[ k ] )
//logger.info( data[ k ] )
//logger.info( '---' )
2023-01-22 09:53:09 +00:00
if ( user [ k ] != data [ k ] ) {
user [ k ] = data [ k ] ;
saveuser = true ;
if ( [ 'TOKEN' , 'LOGIN' , 'EMAIL' ] . includes ( k ) ) updateDatabase = true ;
// attention si LOGIN ou EMAIL change il faut checker qu il n existe pas dejà risque de conflit
}
} ) ;
if ( saveuser ) {
2023-02-21 20:51:11 +00:00
//logger.info( 'mise à jour user profile.json' );
2023-01-22 09:53:09 +00:00
if ( data . TOKEN ) {
user . date _lastLOGIN = new Date ( )
. toISOString ( ) ;
} else {
user . date _update = new Date ( )
. toISOString ( ) ;
}
try {
jsonfile . writeFileSync ( ` ${ config . tribes } / ${ header . xworkon } /users/ ${ UUID } .json ` , user , {
spaces : 2
} ) ;
2023-02-21 20:51:11 +00:00
//logger.info( 'declenche updatabase', updateDatabase )
2023-01-22 09:53:09 +00:00
if ( updateDatabase ) {
// mean index have to be updated
Pagans . updateDatabase ( user , header . xworkon , false ) ;
console . assert ( config . loglevel == "quiet" , 'MISE A JOUR DU TOKEN ou de l\'EMAIL ou du LOGIN' ) ;
}
} catch ( err ) {
2023-02-21 20:51:11 +00:00
logger . info ( 'ERRRRR need to understand update impossible of user: ' + UUID + ' in domain:' + header . xworkon + ' from user ' + header . xpaganid + ' of domain:' + header . xtribe ) ;
logger . info ( 'with data :' , data ) ;
2023-01-22 09:53:09 +00:00
return {
status : 400 ,
data : {
info : [ 'failtoWritefs' ] ,
model : 'Pagans'
}
} ;
}
}
return {
status : 200 ,
data : {
info : [ 'successfulUpdate' ] ,
model : 'Pagans'
}
} ;
} ;
Pagans . deleteUser = ( UUID , header ) => {
// Delete remove from users object UUID and update index
// Activity is not deleted => means some activity can concern an UUID that does not exist anymore.
// update index
const infouser = jsonfile . readFileSync ( ` ${ config . tribes } / ${ header . xworkon } /users/ ${ UUID } .json ` ) ;
Pagans . updateDatabase ( infouser , header . xworkon , true ) ;
fs . removeSync ( ` ${ config . tribes } / ${ header . xworkon } /users/ ${ UUID } .json ` ) ;
return {
status : 200 ,
data : {
info : [ 'successfulDelete' ] ,
modedl : 'Pagans'
}
} ;
} ;
/ *
@ header { xtribeid : client domain name data
A VERIFIER inutile , xworkon : client domain name where user is store and where data are stored
, xuuid : 1 if unknown else if user id auhtneticated
, xlanguage : langue used fr en return referential in this lang
, xauth : TOKEN valid for 24 h ' }
workon = xtribeid in an app client usage
in case of xtribeid = mymaidigit ,
if workon == mymaildigit => admin role on any xworkon
else adlin role only in xworkon specified
@ body { LOGIN : password : }
return { status : 200 , data : { data : { TOKEN , UUID } } }
return { status : 401 , data : { info : [ code list ] , model : referential } }
* /
Pagans . loginUser = ( header , body , checkpsw ) => {
// On recupere tribeid du LOGIN
// ATTENTION xworkon peut être different du user xtribeid
//(cas d'un user qui a des droits sur un autre domain et qui travail sur cet autre domain)
// les function Pagans utilise le domain de travail xWorkon
// il faut donc modifier le header au moment du LOGIN
// pour que l'update du user au moment du LOGIN concerne bien le bon domain
header . xworkon = header . xtribe
const LOGINdom = jsonfile . readFileSync ( ` ${ config . tmp } /loginsglob.json ` ) ;
console . assert ( config . loglevel == "quiet" , LOGINdom )
console . assert ( config . loglevel == "quiet" , body )
if ( ! LOGINdom [ body . LOGIN ] ) {
return {
status : 401 ,
data : { info : [ 'LoginDoesNotExist' ] , model : 'Pagans' }
} ;
}
const logins = jsonfile . readFileSync ( ` ${ config . tribes } / ${ LOGINdom [ body . LOGIN ] } /users/searchindex/logins.json ` ) ;
if ( ! Object . keys ( logins )
. includes ( body . LOGIN ) ) {
return {
status : 401 ,
data : {
info : [ 'LOGINDoesNotExist' ] ,
model : 'Pagans' ,
moreinfo : ` Le login ${ body . LOGIN } does not exist for tribeid ${ LOGINdom [ body . LOGIN ] } `
}
} ;
}
// Load user
const uid = logins [ body . LOGIN ] ;
const getUser = Pagans . getUser ( uid , LOGINdom [ body . LOGIN ] , { users : 'R' } ) ;
2023-02-21 20:51:11 +00:00
logger . info ( 'getPagans' , getUser )
2023-01-22 09:53:09 +00:00
if ( getUser . status != 200 ) {
return { status : 200 , data : { model : 'Pagans' , user : getUser . data . user } } ;
}
const user = getUser . data . user ;
2023-02-21 20:51:11 +00:00
logger . info ( 'user' , user )
2023-01-22 09:53:09 +00:00
if ( checkpsw ) {
const match = bcrypt . compareSync ( body . PASSWORD , user . PASSWORD ) ;
if ( ! match ) {
return {
status : 401 ,
data : {
info : [ 'checkCredentials' ] ,
model : 'Pagans'
}
} ;
}
}
// Mise à jour user pour app LOGIN
user . tribeid = LOGINdom [ body . LOGIN ]
user . TOKEN = jwt . encode ( {
expiration : moment ( )
. add ( 1 , 'day' ) ,
UUID : user . UUID
} , config . jwtSecret ) ;
// on met à jour le header qui authentifie le user connecte
header . xtribe = LOGINdom [ body . LOGIN ]
header . xpaganid = user . UUID ;
header . xauth = user . TOKEN ;
// On modifie xworkon car au LOGIN on est forcemenet identifiable sur tribeid
// xworkon est utiliser pour travailler sur un environnement client different de celui
// de l'appartenace du user
header . xworkon = LOGINdom [ body . LOGIN ] ;
const majuser = Pagans . updateUser ( user . UUID , header , {
UUID : user . UUID ,
TOKEN : user . TOKEN
} ) ;
// Enleve info confidentiel
delete user . PASSWORD ;
if ( user . ACCESSRIGHTS . data [ "Alltribeid" ] ) {
//cas admin on transforme les droits sur tous les tribeid existant
const newaccessrightsdata = { }
jsonfile . readFileSync ( ` ${ config . tribes } /tribeids.json ` )
. forEach ( cid => {
newaccessrightsdata [ cid ] = user . ACCESSRIGHTS . data [ "Alltribeid" ]
} )
user . ACCESSRIGHTS . data = newaccessrightsdata ;
}
// on recupere le menu de l app qui demande le LOGIN si existe dans user.ACCESSRIGHTS.app[]
// header['X-app'] = tribeid:Projet pour récuperer le menu correspondant
console . assert ( config . loglevel == "quiet" , "header.xapp" , header . xapp )
console . assert ( config . loglevel == "quiet" , "user.ACCESSRIGHTS.app[header.xapp]" , user . ACCESSRIGHTS . app [ header . xapp ] ) ;
return {
status : 200 ,
data : {
model : "Pagans" ,
info : [ 'loginSuccess' ] ,
user : user
}
} ;
} ;
Pagans . getlinkwithoutpsw = async ( EMAIL , header ) => {
// check le domain d'appartenance de l'eamail dans /tribes/emailsglob.json={email:cleintId}
// on remplace le header.xtribeid
const domforemail = jsonfile . readFileSync ( ` ${ config . tribes } /emailsglob.json ` , 'utf-8' ) ;
if ( domforemail [ EMAIL ] ) {
header . xtribe = domforemail [ EMAIL ]
} else {
return { status : 404 , info : { model : 'Pagans' , info : [ 'emailnotfound' ] , moreinfo : "email does not exist in /emailsglob.json" } } ;
}
// recupere le uuid du user dans /tribes/tribeid/users/searchindex/emails.json
// puis l'ensemble des info des user du domain /uuids.json
// infoforuuid[uuidforemail[EMAIL]] permet de récupérer toutes info du user, droit, etc...
const uuidforemail = jsonfile . readFileSync ( ` ${ config . tribes } / ${ header . xtribe } /users/searchindex/emails.json ` , 'utf8' ) ;
const infoforuuid = jsonfile . readFileSync ( ` ${ config . tribes } / ${ header . xtribe } /users/searchindex/uids.json ` , 'utf8' ) ;
// On recupere le modele d'email appemailinfo qui doit être présent dans clientconf.json
let confdom = jsonfile . readFileSync ( ` ${ config . tribes } / ${ header . xtribe } /clientconf.json ` , 'utf8' ) ;
let checkinfomail = "" ;
if ( ! confdom . appemailinfo ) {
checkinfomail += ' Erreur de clientconfig il manque un objet appemailinfo pour poursuivre' ;
}
if ( checkinfomail != "" ) {
2023-02-21 20:51:11 +00:00
logger . info ( ` Pb de config pour ${ header . xtribe } ${ checkinfomail } ` )
2023-01-22 09:53:09 +00:00
return {
status : 500 ,
info : {
model : 'Pagans' ,
info : [ 'objectmissingclientconf' ] ,
moreinfo : checkinfomail
}
} ;
}
let simulelogin ;
try {
simulelogin = await Pagans . loginUser ( header , {
LOGIN : infoforuuid [ uuidforemail [ EMAIL ] ] [ 0 ] ,
PASSWORD : ""
} , false ) ;
2023-02-21 20:51:11 +00:00
logger . info ( 'info simulelogin' , simulelogin )
2023-01-22 09:53:09 +00:00
} catch ( err ) {
return {
status : 501 ,
info : {
model : 'Pagans' ,
info : [ 'loginImpossible' ] ,
moreinfo : "Impossible de se loger avec " + infoforuuid [ uuidforemail [ EMAIL ] ] [ 0 ]
}
} ;
}
const url = ` ${ config . rootURL } ?xauth= ${ simulelogin . data . TOKEN } &xuuid= ${ simulelogin . data . UUID } &xtribeid= ${ simulelogin . data . tribeid } &xworkOn= ${ header . xworkon } &xlang= ${ header . xlang } `
2023-02-21 20:51:11 +00:00
//logger.info('envoi email avec' + url)
2023-01-22 09:53:09 +00:00
confdom . appemailinfo . msg . destperso = [ { } ] ;
confdom . appemailinfo . msg . destperso [ 0 ] . email = EMAIL ;
confdom . appemailinfo . msg . destperso [ 0 ] . subject = "Lien de réinitialisation valable 1h"
confdom . appemailinfo . msg . destperso [ 0 ] . titre = "Vous avez oublier votre mot de passe"
confdom . appemailinfo . msg . destperso [ 0 ] . texte = `
< p style = 'color: #999999; font-size: 16px; line-height: 24px; margin: 0;text-align:justify;' >
Bonjour , < br > Vous nous avez signalé que vous avez oublié votre mot de passe pour cette email .
Avec le lien suivant vous allez pouvoir utiliser votre interface 1 h maximum .
< a href = "${url}" > Clicker ICI < / a > . < b r >
Nous vous conseillons de changer votre mot de passe . < / p >
`
2023-02-21 20:51:11 +00:00
//logger.info('envoi header :', header);
2023-01-22 09:53:09 +00:00
Outputs . sendMailcampain ( confdom . appemailinfo . msg , header ) ;
2023-02-21 20:51:11 +00:00
logger . info ( confdom . appemailinfo ) ;
2023-01-22 09:53:09 +00:00
return {
status : 200 ,
info : {
model : 'Pagans' ,
info : [ 'emailsentforReinit' ] ,
moreinfo : 'EMAIL sent with unique link ' + url
}
} ;
}
module . exports = Pagans ;