update checkdata.js

This commit is contained in:
2023-03-27 07:52:21 +02:00
parent a03e35c9e2
commit d0a3b10cfe
83 changed files with 1608 additions and 825 deletions

View File

@@ -85,7 +85,7 @@ Contracts.initActiontodo = async ( envoie ) => {
const actiondone = await Contracts[ todo.action ]( todo, envoie );
todo.datesRun.push( moment( new Date() )
.format( 'YYYYMMDD HH:mm:ss' ) );
//console.log("actiondone", actio jsonfile.writeFileSyncndone);
//console.log("actiondone"
log.actionlist += "STATUS:" + actiondone.status + " -- " + listaction[ action ] + "\n";
if( actiondone.status == 200 ) {
todo.error = "";

View File

@@ -12,11 +12,11 @@ const config = require( '../tribes/townconf.js' );
const checkdata = require( `../nationchains/socialworld/contracts/checkdata.js`);
/*
Message manager
* Manage apixtribe message at different level
* Manage apxtrib message at different level
* this means that an object (most often a user or a contact) want to send a question to an other user.
To know more http://gitlab.ndda.fr/philc/apixtribe/-/wikis/HOWTONotification
To know more http://gitlab.ndda.fr/philc/apxtrib/-/wikis/HOWTONotification
*/
const Messages = {};
@@ -35,7 +35,7 @@ Messages.byEmailwithmailjet = ( tribeid, msg ) => {
TextPart:"texte content",
HTMLPart:"html content"
}]
If tribeid has a mailjet account it use it if not then it use the apixtribe @mailjetconf = {apikeypub:, apikeypriv:, From:{Email:,Name:}}
If tribeid has a mailjet account it use it if not then it use the apxtrib @mailjetconf = {apikeypub:, apikeypriv:, From:{Email:,Name:}}
This send a bunch of messages check the mailjet account used
FYI: Basic account is 200 email /days 6000 /month
Log is stored into
@@ -48,12 +48,12 @@ Messages.byEmailwithmailjet = ( tribeid, msg ) => {
if( confclient.smtp && confclient.smtp.mailjet ) {
mailjetconf = confclient.smtp.mailjet;
} else {
const confapixtribe = fs.readJsonSync( `${config.tribes}/${config.mayorId}/clientconf.json` );
if( !( confapixtribe.smtp && confapixtribe.smtp.mailjet ) ) {
return { status: 403, data: { models: "Messages", info: [ "nosmtpmailjet" ], moreinfo: "missing smtpmailjet parameter in apixtribe contact your admin to activate an mailjet account on this server." } }
const confapxtrib = fs.readJsonSync( `${config.tribes}/${config.mayorId}/clientconf.json` );
if( !( confapxtrib.smtp && confapxtrib.smtp.mailjet ) ) {
return { status: 403, data: { models: "Messages", info: [ "nosmtpmailjet" ], moreinfo: "missing smtpmailjet parameter in apxtrib contact your admin to activate an mailjet account on this server." } }
}
tribeidsender = "apixtribe";
mailjetconf = confapixtribe.smtp.mailjet;
tribeidsender = "apxtrib";
mailjetconf = confapxtrib.smtp.mailjet;
}
//add from from setings account
const MSG = msg.map( m => { m.From = mailjetconf.From; return m; } );
@@ -79,7 +79,7 @@ Messages.byEmailwithmailjet = ( tribeid, msg ) => {
};
Messages.buildemail = ( tribeid, tplmessage, data ) => {
/* @tribeid => client concerned by sending email get info from clientconf.json (customization, useradmin:{ EMAIL,LOGIN} , ...)
@tplmessage => folder where template is available (ex: apixtribe/referentials/dataManagement/template/order)
@tplmessage => folder where template is available (ex: apxtrib/referentials/dataManagement/template/order)
@data { destemail = email to
if destuuid => then it get user EMAIL if exiat
subject = mail subject
@@ -279,7 +279,7 @@ Messages.notification = ( data, header ) => {
};
}
//by default store in tmp/notification this is only for sysadmin
// user adminapixtribe
// user adminapxtrib
let notdest = `${config.tmp}`;
if( data.app ) {

View File

@@ -1,18 +1,14 @@
const bcrypt = require( 'bcrypt' );
const fs = require( 'fs-extra' );
const path = require( 'path' );
const jsonfile = require( 'jsonfile' );
const glob = require( 'glob' );
const jwt = require( 'jwt-simple' );
const moment = require( 'moment' );
const axios = require( 'axios' );
const UUID = require( 'uuid' );
const Outputs = require( './Outputs.js' );
const config = require( '../tribes/townconf.js' );
const checkdata = require( `../nationchains/socialworld/contracts/checkdata.js`);
const bcrypt = require("bcrypt");
const fs = require("fs-extra");
const glob = require("glob");
const jwt = require("jwt-simple");
const axios = require("axios");
const config = require("../tribes/townconf.js");
const Odmdb = require('../models/Odmdb.js');
/*
Blockchain manager
* Manage network directory
* Manage network directory of nations and towns
* read Blockchain and search,
* submit a transaction (now) or contract (futur) to store from userA.pubkey to userB.pubkey a number of AXESS
* mine to be able to register a block and create AXESS
@@ -21,85 +17,146 @@ Blockchain manager
*/
const Nationchains = {};
Nationchains.init = () => {
console.group( 'init Nationchains' );
}
console.group("init Nationchains");
};
Nationchains.synchronize = () => {
/*
Run process to communicate with a list of apixtribe instance to update transaction and earn AXP
/*
Run process to communicate with a list of apxtrib instance to update transaction and earn AXP
To creation of a new tribeid or a new login
*/
//update himself then send to other information
if( process.env.NODE_ENV != "prod" ) {
// Not concerned
return {}
}
const initcurrentinstance = {
"fixedIP": "",
"lastblocknumber": 0,
"firsttimeupdate": 0,
"lastimeupdate": 0,
"positifupdate": 0,
"negatifupdate": 0,
"pubkeyadmin": "",
"tribeids": [],
"logins": [],
"knowninstance": []
};
let currentinstance = initcurrentinstance;
try {
currentinstance = fs.readFileSync( `${config.tribes}/${config.mayorId}/nationchains/nodes/${config.rootURL}`, 'utf-8' )
} catch ( err ) {
console.log( 'first init' )
}
const loginsglob = fs.readJsonSync( `${config.tmp}/loginsglob.json`, 'utf-8' );
currentinstance.logins = Object.keys( loginsglob );
currentinstance.tribeids = [ ...new Set( Object.values( loginsglob ) ) ];
currentinstance.instanceknown = glob.Sync( `${config.tribes}/${config.mayorId}/nationchains/nodes/*` );
//Save it
fs.outputJsonSync( `${config.tribes}/${config.mayorId}/nationchains/nodes/${config.rootURL}`, currentinstance );
// proof of work
// try to find a key based on last block with difficulty
// if find then send to all for update and try to get token
// in any case rerun Nationchains.synchronize()
currentinstance.instanceknown.forEach( u => {
if( u != config.rootURL ) {
//send currentinstance info and get back state of
axios.post( `https://${u}/nationchains/push`, currentinstance )
.then( rep => {
newdata = rep.payload.moreinfo
//Available update info
fs.readJson( `${config.tribes}/${config.mayorId}/nationchains/nodes/${u}`, ( err, data ) => {
if( err ) {
data.negatifupdate += 1;
data.lasttimeupdate = Date.now();
} else {
data.positifupdate += 1;
data.lastimeupdate = Date.now();
data.tribeids = newdata.tribeids;
data.logins = newdata.logins;
data.lastblocknumber = newdata.lastblocknumber;
newdata.knowninstance.forEach( k => {
if( !data.knowninstance.includes( k ) ) {
data.knowninstance.push( k );
//init the domain for next update
initcurrentinstance.firsttimeupdate = Date.now();
fs.outputJson( `${config.tribes}/${config.mayorId}/nationchains/nodes/${k}`, initcurrentinstance, 'utf-8' )
}
} )
}
//save with info
fs.outputJson( `${config.tribes}/${config.mayorId}/nationchains/nodes/${u}`, data );
} )
} )
.catch( err => {
//Not available
data.negatifupdate += 1;
data.lasttimeupdate = Date.now();
fs.outputJson( `${config.tribes}/${config.mayorId}/nationchains/nodes/${u}`, data );
} );
}
} );
//update himself then send to other information
if (process.env.NODE_ENV != "prod") {
// Not concerned
return {};
}
const initcurrentinstance = {
fixedIP: "",
lastblocknumber: 0,
firsttimeupdate: 0,
lastimeupdate: 0,
positifupdate: 0,
negatifupdate: 0,
pubkeyadmin: "",
tribeids: [],
logins: [],
knowninstance: [],
};
let currentinstance = initcurrentinstance;
try {
currentinstance = fs.readFileSync(
`${config.tribes}/${config.mayorId}/nationchains/nodes/${config.rootURL}`,
"utf-8"
);
} catch (err) {
console.log("first init");
}
const loginsglob = fs.readJsonSync(`${config.tmp}/loginsglob.json`, "utf-8");
currentinstance.logins = Object.keys(loginsglob);
currentinstance.tribeids = [...new Set(Object.values(loginsglob))];
currentinstance.instanceknown = glob.Sync(
`${config.tribes}/${config.mayorId}/nationchains/nodes/*`
);
//Save it
fs.outputJsonSync(
`${config.tribes}/${config.mayorId}/nationchains/nodes/${config.rootURL}`,
currentinstance
);
// proof of work
// try to find a key based on last block with difficulty
// if find then send to all for update and try to get token
// in any case rerun Nationchains.synchronize()
currentinstance.instanceknown.forEach((u) => {
if (u != config.rootURL) {
//send currentinstance info and get back state of
axios
.post(`https://${u}/nationchains/push`, currentinstance)
.then((rep) => {
newdata = rep.payload.moreinfo;
//Available update info
fs.readJson(
`${config.tribes}/${config.mayorId}/nationchains/nodes/${u}`,
(err, data) => {
if (err) {
data.negatifupdate += 1;
data.lasttimeupdate = Date.now();
} else {
data.positifupdate += 1;
data.lastimeupdate = Date.now();
data.tribeids = newdata.tribeids;
data.logins = newdata.logins;
data.lastblocknumber = newdata.lastblocknumber;
newdata.knowninstance.forEach((k) => {
if (!data.knowninstance.includes(k)) {
data.knowninstance.push(k);
//init the domain for next update
initcurrentinstance.firsttimeupdate = Date.now();
fs.outputJson(
`${config.tribes}/${config.mayorId}/nationchains/nodes/${k}`,
initcurrentinstance,
"utf-8"
);
}
});
}
//save with info
fs.outputJson(
`${config.tribes}/${config.mayorId}/nationchains/nodes/${u}`,
data
);
}
);
})
.catch((err) => {
//Not available
data.negatifupdate += 1;
data.lasttimeupdate = Date.now();
fs.outputJson(
`${config.tribes}/${config.mayorId}/nationchains/nodes/${u}`,
data
);
});
}
});
};
Nationchains.create = (conf) => {
/*
@conf from a nationchains/socialworld/setup/townSetup {object, nationName, townName, dns}
@return
*/
const res = {};
if (conf.object=="town"){
Odmdb.create("nationchains/socialworld/objects","town",conf);
}
const nation_town = fs.readJsonSync(
"./nationchains/socialworld/objects/towns/searchindex/towns_nationId_townId.json"
);
if (!ObjectKeys(nation_town).includes(conf.nationName)) {
res.status = 404;
res.info = `your nationName ${conf.nationName} does not exist you have to choose an existing one`;
return res;
}
if (nation_town[conf.nationName].includes(conf.townName)) {
res.status = 409;
res.info = `This conf.townName already exist you have to find a unique town name per nation`;
return res;
}
const towndata = {
uuid: conf.townName,
nationid: conf.nationName,
url: `${conf.townName}.${conf.nationName}.${conf.dns}`,
status: (conf.dns=="unchain")? "unchain" : "tochain",
};
const metatown=fs.readJsonSync('./nationchains/socialworld/metaobject/towns.json');
Odmdb.add(objectpath, towns, metatown,towndata)
fs.outputJsonSync(
`./nationchains/socialworld/objects/towns/${townName}.json`,
towndata
);
res.status=200
res.info=`${townName} create for ${nationName} nation`;
return res
};
module.exports = Nationchains;

View File

@@ -1,10 +1,16 @@
const glob = require( 'glob' );
const path = require( 'path' );
const fs = require( 'fs-extra' );
const config = require( '../tribes/townconf.js' );
const glob = require("glob");
const path = require("path");
const fs = require("fs-extra");
//const config = require( '../tribes/townconf.js' );
const check = require(`../nationchains/socialworld/contracts/checkdata.js`);
/* This manage Objects for indexing and check and act to CRUD
objectpath/objects/schema/objectName.json
/objectNames/searchindes/objectName_valueofkey_uuildlist.json
/objectNames/uuid.json
*/
const Odmdb = {};
/*
Input: metaobject => data mapper of Key: Value
@@ -13,5 +19,127 @@ Input: metaobject => data mapper of Key: Value
objname + action index => update /searcindex of objects concern
*/
Odmdb.schema = (objectPath, objectName) => {
// Return schema if exist and objectpath contain objectName { status:200;data:schema}
if (!fs.existsSync(`${objectPath}/${objectName}`))
return {
status: 404,
info: "|odmdb|objectpathnamedoesnotexist",
moreinfo: `${objectPath}/${objectName}`,
};
if (!fs.existsSync(`${objectPath}/schema/${objectName}.json`)) {
return {
status: 404,
info: `|odmdb|schemanotfound`,
moreinfo: `file not found ${objectPath}/schema/${objectName}.json`,
};
} else {
return {
status: 200,
data: fs.readJsonSync(`${objectPath}/schema/${objectName}.json`),
};
}
};
module.exports = Odmdb;
Odmdb.check = (objectPath, objectName, data) => {
/*
@objectPath path to the folder that contain /objects/objectName/ /objectsInfo/objectName_lg.json /objectsMeta/objectName.json
@objectName name of object
@data data to check based on objectsMeta definition
*/
const schema = Odmdb.schema(objectPath, objectName);
if (schema.status != 200) return schema;
console.log("SCHEMA for checking:");
console.log(schema.data);
console.log("DATA to check:");
console.log(data);
const validate = checkdata.schema.data(schema.data,data)
/*const ajv = new Ajv({strict:"log"});
const validate = ajv.compile(schema.data);
const valid = validate(data)
console.log("valid:",valid)
*/
};
Odmdb.search = (objectPath, objectName, search) => {
/*
@search= {
txt: string,
algo: match | pattern | fuzzy
fieldstring:[list of field],
indexfilter:{index1:[val1,val2 | ] }
}
Return data:[uuids]
example: search exact match hill in townId
heavy search={txt:"hill",algo:"match",fieldstring:"toxnId"}
light search={txt:"hill", algo:"match", indexfilter:{"key":"townId","value":[]}}
light search={txt:"hill", algo:"match", indexfilter:{"key":"nationId","value":"ants"}}
*/
const schema = Odmdb.schema(objectPath, objectName);
if (schema.status != 200) return schema;
};
Odmdb.get = (objectPath, objectName, uuidprimarykeyList, fieldList) => {
/*
@uuidprimarykeyList list of uuid requested
@fieldList key to return for each object
Return objectName {status:200; data:{found:[{primarykey,field}],notfound:[uuid]}
if all primarykey exist then data.notfound does not exist
if all primarykey does not exist data.found does not exist
*/
const res = { status: 200, data: {} };
uuidprimarykeyList.forEach((id) => {
if (fs.existsSync(`${objectPath}/${objectName}/${id}.json`)) {
if (!res.data.found) res.data.found = [];
const objectdata = fs.readJsonSync(
`${objectPath}/${objectName}/${id}.json`
);
if (!fieldList) {
res.data.found.push(objectdata);
} else {
const objinfo = {};
fieldlList.forEach((k) => {
if (objectdata[k]) objinfo[k] = objectdata[k];
});
res.data.found.push(objinfo);
}
} else {
if (!res.data.notfound) res.data.notfound = [];
}
});
return res;
};
Odmdb.create = (objectPath, objectName, data) => {
/*
Create an objects data into objectName
@objectPath path to the folder that contain /objects/objectName/ /objectsInfo/objectName_lg.json /objectsMeta/objectName.json
@objectName name of object
@data data to check based on objectsMeta definition
*/
};
Odmdb.update = (objectPath, objectName, data) => {
/*
Create an objects data into objectName
@objectPath path to the folder that contain /objects/objectName/ /objectsInfo/objectName_lg.json /objectsMeta/objectName.json
@objectName name of object
@data data to check based on objectsMeta definition
*/
};
Odmdb.delete = (objectPath, objectName, data) => {
/*
Create an objects data into objectName
@objectPath path to the folder that contain /objects/objectName/ /objectsInfo/objectName_lg.json /objectsMeta/objectName.json
@objectName name of object
@data data to check based on objectsMeta definition
*/
};
console.log("test Odmdb");
console.log(
Odmdb.check(
"/media/phil/usbfarm/apxtrib/nationchains/socialworld/objects",
"nations",
{ nationId: "123", status: "unchain" }
)
);
module.exports = Odmdb;

View File

@@ -435,7 +435,7 @@ Outputs.addjson = function ( data, header ) {
try {
fs.outputJsonSync( header.destinationfile + '/' + header.filename, data.jsonp );
if( data.callback ) {
const execCB = require( `${config.mainDir}/models/tribeid/${header.xworkon
const execCB = require( `${__base}/models/tribeid/${header.xworkon
}` );
execCB[ data.callback ]();
}

View File

@@ -350,7 +350,7 @@ Outputs.addjson = function ( data, header ) {
try {
fs.outputJsonSync( header.destinationfile + '/' + header.filename, data.jsonp );
if( data.callback ) {
const execCB = require( `${config.mainDir}/models/tribeid/${header.xworkon
const execCB = require( `${__base}/models/tribeid/${header.xworkon
}` );
execCB[ data.callback ]();
}

View File

@@ -1,6 +1,5 @@
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' );

View File

@@ -239,7 +239,7 @@ Referentials.update = ( tribeid, source, name ) => {
}
}
};
//console.log( Referentials.update( 'apixtribe', "object", "user" ) )
//console.log( Referentials.update( 'apxtrib', "object", "user" ) )
Referentials.genereobjet = ( tribeid, destination, tplmustache, objet, filtre ) => {
/* @TODO

View File

@@ -204,7 +204,7 @@ Referentials.update = ( tribeid, source, name ) => {
}
}
};
//console.log( Referentials.update( 'apixtribe', "object", "user" ) )
//console.log( Referentials.update( 'apxtrib', "object", "user" ) )
Referentials.genereobjet = ( tribeid, destination, tplmustache, objet, filtre ) => {
/* @TODO

View File

@@ -2,6 +2,7 @@ const fs = require( 'fs-extra' );
const path = require( 'path' );
const dnsSync = require( 'dns-sync' );
const Mustache = require( 'mustache' );
const Odmdb= require('./Odmdb.js');
const Setup = {};
@@ -9,11 +10,11 @@ if( !fs.existsSync( '/etc/nginx/nginx.conf' ) ) {
console.log( '\x1b[31m Check documentation, nginx have to be installed on this server first, no /etc/nginx/nginx.conf available' );
process.exit();
}
if( !fs.existsSync( '../config.js' ) ) {
console.log( `\x1b[42m####################################\nWellcome into apixtribe, this is a first install.\nWe need to make this server accessible from internet subdomain.domain to current IP. This setup will create your unique tribeid, with an admin login user to let you connect to the parameter interface.\nCheck README's project to learn more. more.\n#####################################\x1b[0m` );
const confdata = fs.readJsonSync( path.normalize( `${__dirname}/../setup/configsetup.json` ) );
console.log( 'Current setup conf from :\n' + path.normalize( `${__dirname}/../setup/configsetup.json` + '\nChange with relevant setup data and rerun yarn setup' ) );
console.log( confdata )
if( !fs.existsSync( `./tribes/townconf.json` ) ) {
console.log( `\x1b[42m####################################\nWellcome into apxtrib, this is a first install.\nWe need to make this server accessible from internet subdomain.domain to current IP. This setup will create your unique tribeid, with an admin login user to let you connect to the parameter interface.\nCheck README's project to learn more. more.\n#####################################\x1b[0m` );
const townSetup = fs.readJsonSync( './nationchains/socialworld/setup/townSetup.json') ;
console.log( `Current setup conf from :./nationchains/socialworld/setup/townSetup.json\nChange with relevant setup data and rerun yarn setup` ) ;
console.log( townSetup )
const readline = require( 'readline' );
const rl = readline.createInterface( {
input: process.stdin,
@@ -21,16 +22,26 @@ if( !fs.existsSync( '../config.js' ) ) {
} );
rl.question( 'This is the data from setup/configsetup.json used, is it correct to use as first install (Yes/no)?', function ( rep1 ) {
let quest = `This is a production install, please check that ${confdata.subdomain}.${confdata.domain} IP is well redirect to tour server`;
let quest = `This is a production install, please check that ${townSetup.townName}.${townSetup.nationName}.${townSetup.dns} IP is well redirect to tour server`;
if( rep1 !== "Yes" ) process.exit( 0 );
if( confdata.domain == 'local.fr' ) {
quest = `This is a development installation, please add in your /etc/hosts "127.0.0.1 ${confdata.subdomain}.${confdata.domain} " `;
if( townSetup.dns == 'unchain' ) {
quest = `This is a development installation, please add in your /etc/hosts 127.0.0.1 ${townSetup.townName}.${townSetup.nationName}.${townSetup.dns} `;
}
rl.question( quest + '\nAre you sure to set this? (Yes/no)', function ( rep2 ) {
if( rep2 == "Yes" ) {
const check = Setup.checkdata( confdata );
const check = Setup.check( townSetup );
if( check == "" ) {
Setup.config( confdata );
const townconf=fs.readJsonSync('./nationchains/socialworld/setup/townSetup.json')
// create tribes folder with townconf.json
fs.outputJsonSync(`./tribes/townconf.json`,{...townSetup,...townconf},{spaces:2})
const Nationchains = require('./Nationchains');
const Tribes = require('./Tribes');
const Pagans = require('./Pagans');
townSetup.object="town"
Nationschains.create(townSetup);
Tribes.create(townSetup);
Pagans.create(townSetup);
//Setup.config( townSetup );
} else {
console.log( check );
}
@@ -48,93 +59,100 @@ if( !fs.existsSync( '../config.js' ) ) {
console.log( 'Carefull you have already a config.js that is running. If you want to change remove config.js file and run again yarn setup' );
}
Setup.checkdata = conf => {
let rep = "";
if( ![ 'dev', 'prod' ].includes( conf.mode ) ) {
rep += "mode have to be 'dev' or 'prod' currently it's " + conf.mode + "\n";
Setup.check = conf => {
var rep = "";
const nation_town=fs.readJsonSync('./nationchains/socialworld/objects/towns/searchindex/towns_nation_uuid.json');
if (!ObjectKeys(nation_town).includes(conf.nationName)){
rep+=`your nationName ${conf.nationName} does not exist you have to choose an existing one`;
}
if (nation_town[conf.nationName].includes(conf.townName)){
rep+=`This conf.townName already exist you have to find a unique town name per nation`;
}
const getnation = Odmdb.get('./nationchains/socialworld/objects','towns',[conf.NationName];[nationId])
if getnation.data.notfound
conf.language.forEach( l => {
if( ![ "fr", "en", "it", "de", "sp" ].includes( l ) ) {
rep += l + " Only fr,en,it,de,sp are available \n";
}
} );
if( !fs.existsSync( `/home/${conf.linuxuser}` ) ) {
rep += `/home/${conf.linuxuser} does not exist, user has to be create with a /home on this server\n`;
if( !fs.existsSync( `/home/${conf.sudoerUser}` ) ) {
rep += `/home/${conf.sudoerUser} does not exist, user has to be create with a /home on this server\n`;
}
// avant eslint if( !( /^[a-z\s\-]+$/.test( conf.druidid ) ) ) {
if( !( /^[a-z\s-]+$/.test( conf.druidid ) ) ) {
rep += `${conf.druidid} have to contain only a-z characters `;
}
// add a check later have to be unique if not in dev
if( !( /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&.])[A-Za-z\d$@$!%*?&.{}:|\s]{8,}/.test( conf.genericpsw ) ) ) {
rep += "Give a generic pasword for all your tribeid's user,they will change it min 8 char special char upper lower case and number"
try {
if ("true"== execSync("timeout 2 sudo id && sudo=\"true\" || sudo=\"false\";echo \"$sudo\"").toString().trim().split(/\r?\n/).slice(-1)) {
rep+=`${sudoerUser} is not sudoer please change this `;
} ;
}catch(err){
console.log(err);
rep+=" Check your user it seems to not be a sudoer"
}
if( conf.jwtsecret.length < 32 ) {
rep += "Your jwtsecretkey must have at least 32 characters"
}
if( conf.mode != 'dev' && !dnsSync.resolve( `${conf.subdomain}.${conf.domain}` ) ) {
rep += `\nresolving ${conf.subdomain}.${conf.domain} will not responding valid IP, please setup domain redirection IP before runing this script`
if( conf.dns != 'unchain' && !dnsSync.resolve( `${conf.townName}.${conf.nationName}.${conf.dns}` ) ) {
rep += `\nresolving $${conf.townName}.${conf.nationName}.${conf.dns} will not responding valid IP, please setup domain redirection IP before runing this script`
}
return rep
};
Setup.config = ( confdata ) => {
Setup.config = ( townSetup ) => {
// Init this instance with a .config.js
Setup.configjs( confdata );
// Create tribeid space + a user admin + webspace withe apixtribe webapp install
Setup.druidid( confdata );
Setup.configjs( townSetup );
// Create tribeid space + a user admin + webspace withe apxtrib webapp install
Setup.druidid( townSetup );
};
Setup.configjs = ( confdata ) => {
Setup.configjs = ( townSetup ) => {
// Set /config.js
let confapixtribe = fs.readFileSync( './setup/config.mustache', 'utf-8' );
fs.writeFileSync( './config.js', Mustache.render( confapixtribe, confdata ), 'utf-8' );
let confapxtrib = fs.readFileSync( './setup/config.mustache', 'utf-8' );
fs.writeFileSync( './config.js', Mustache.render( confapxtrib, townSetup ), 'utf-8' );
if( fs.existsSync( './config.js' ) ) {
console.log( 'config.js successfully created.' );
} else {
console.log( "config.js not created, check what's wrong in tpl:", confapixtribe );
console.log( "for data :", confdata );
console.log( "config.js not created, check what's wrong in tpl:", confapxtrib );
console.log( "for data :", townSetup );
process.exit();
}
};
Setup.druidid = ( confdata ) => {
Setup.druidid = ( townSetup ) => {
// create a tribeid with a user that will admin this instance into /tribes/tribeid /users
const config = require( '../config.js' );
// Need to do it on setup this is also done again in models/Tribes.js
console.log( `${config.tribes}/${confdata.druidid}` )
fs.ensureDirSync( `${config.tribes}/${confdata.druidid}` );
console.log( `${config.tribes}/${townSetup.druidid}` )
fs.ensureDirSync( `${config.tribes}/${townSetup.druidid}` );
[ 'users', 'www', 'referentials', 'nationchains' ].forEach( r => {
fs.copySync( `${config.mainDir}/setup/tribes/apixtribe/${r}`, `${config.tribes}/${confdata.druidid}/${r}` );
fs.copySync( `${__base}/setup/tribes/apxtrib/${r}`, `${config.tribes}/${townSetup.druidid}/${r}` );
} )
/* const confcli = JSON.parse( Mustache.render( fs.readFileSync( `${config.mainDir}/setup/tribes/apixtribe/clientconf.mustache`, 'utf8' ), confdata ) );
fs.outputJsonSync( `${config.tribes}/${confdata.druidid}/clientconf.json`, confcli );
/* const confcli = JSON.parse( Mustache.render( fs.readFileSync( `${__base}/setup/tribes/apxtrib/clientconf.mustache`, 'utf8' ), townSetup ) );
fs.outputJsonSync( `${config.tribes}/${townSetup.druidid}/clientconf.json`, confcli );
// Create a new tribeid + admin user for this tribeid
// with access to {druidid}:webapp as admin
*/
*/
const Tribes = require( '../models/Tribes.js' );
const access = { app: {}, data: {} }
access.app[ `${confdata.druidid}:webapp` ] = "admin";
access.data[ confdata.druidid ] = { "users": "CRUDO", "referentials": "CRUDO", "www": "CRUDO" };
access.app[ `${townSetup.druidid}:webapp` ] = "admin";
access.data[ townSetup.druidid ] = { "users": "CRUDO", "referentials": "CRUDO", "www": "CRUDO" };
const createclient = Tribes.create( {
tribeid: confdata.druidid,
genericpsw: confdata.genericpsw,
lanquageReferential: confdata.language,
tribeid: townSetup.druidid,
genericpsw: townSetup.genericpsw,
lanquageReferential: townSetup.language,
useradmin: {
LOGIN: confdata.login,
xlang: confdata.language[ 0 ],
LOGIN: townSetup.login,
xlang: townSetup.language[ 0 ],
ACCESSRIGHTS: access
}
} );
if( createclient.status == 200 ) {
console.log( `Your tribeid domain was created with login : ${confdata.login} and password: ${confdata.genericpsw}, change it after the 1st login on https://${confdata.subdomain}.${confdata.domain}` );
console.log( `Your tribeid domain was created with login : ${townSetup.login} and password: ${townSetup.genericpsw}, change it after the 1st login on https://${townSetup.subdomain}.${townSetup.domain}` );
// Create nginx conf for a first install
const confnginx = fs.readFileSync( './setup/nginx/nginx.conf.mustache', 'utf8' );
fs.outputFileSync( '/etc/nginx/nginx.conf', Mustache.render( confnginx, confdata ), 'utf-8' );
// Create a spacedev for webapp of apixtribe
fs.outputFileSync( '/etc/nginx/nginx.conf', Mustache.render( confnginx, townSetup ), 'utf-8' );
// Create a spacedev for webapp of apxtrib
// that will be accesible in prod from https://subdomain.domain/ and in dev http://webapp.local.fr
const addspaceweb = Tribes.addspaceweb( {
setup: true,
dnsname: [ `${confdata.subdomain}.${confdata.domain}` ],
mode: confdata.mode,
tribeid: confdata.druidid,
dnsname: [ `${townSetup.subdomain}.${townSetup.domain}` ],
mode: townSetup.mode,
tribeid: townSetup.druidid,
website: 'webapp',
pageindex: "app_index_fr.html"
} );

View File

@@ -1,13 +1,10 @@
const fs = require( 'fs' );
const formidable = require( 'formidable' );
const jsonfile = require( 'jsonfile' );
const fs = require( 'fs-extra' );
const path = require( 'path' );
const glob = require( 'glob' );
const mustache = require( 'mustache' );
const moment = require( 'moment' );
// Check if package is installed or not to pickup the right config file
const config = require( '../tribes/townconf.js' );
//const config = require( '../tribes/townconf.js' );
const config={}
const Tags = {};
/*
@@ -64,7 +61,7 @@ Tags.getfile = ( filename, req ) => {
} );
return {
status: 200,
payload: { moreinfo: "Declenche tag", filename: `${config.mainDir}/public/imgtg.png` }
payload: { moreinfo: "Declenche tag", filename: `${__base}/public/imgtg.png` }
}
}
return { status: 404, payload: {} }
@@ -226,4 +223,89 @@ Tags.dataloadstat = ( tribeid ) => {
console.log(ar.some(el => el[0] == 1 && el[1] == 1))
console.log(ar.some(el => el == [1, 3]))
*/
Tags.nginxlog=(pathFile)=>{
/*
Read an nginx log file and return
@TODO standardiser le log nginx pour recuperer des données (IP,...)
@return {visites:{year:month:{day:number of visites}},
visitors:{year:month:{day: number of unique visitors for the day}}
year: number of unique visitors for the year}
month:month : number of unique visitors for the month]
}
*/
const log= fs.readFileSync(pathFile,'utf-8');
const logs=log.split('\n');
console.log(`nombre ligne ${logs.length}`)
const stat={visits:{},visitors:{}};
const visitor={}
var previousdt=moment();
var previoususeragent="";
console.log(moment(previousdt).format('DD/MMM/YYYY:hh:mm:ss'))
logs.forEach(l=>{
const elt= l.split('##');
const useragent = (elt[2] && elt[2].split("\" \"")[1]) ? elt[2].split("\" \"")[1]:"unknown";
//elt[0] = [30/Jun/2022:15:15:53 +0200]
const dttime = moment(elt[0].split(' ')[0].substring(1),'DD/MMM/YYYY:hh:mm:ss');
['visits','visitors'].forEach(ch=>{
if (!stat[ch][dttime.format('YYYY')]) stat[ch][dttime.format('YYYY')]={};
if (!stat[ch][dttime.format('YYYY')][dttime.format('MMM')]) stat[ch][dttime.format('YYYY')][dttime.format('MMM')]={}
if (!stat[ch][dttime.format('YYYY')][dttime.format('MMM')][dttime.format('DD')]) stat[ch][dttime.format('YYYY')][dttime.format('MMM')][[dttime.format('DD')]]=0
if (!visitor[dttime.format('YYYY')]) visitor[dttime.format('YYYY')]={};
if (!visitor[dttime.format('YYYY')][dttime.format('MMM')]) visitor[dttime.format('YYYY')][dttime.format('MMM')]={}
if (!visitor[dttime.format('YYYY')][dttime.format('MMM')][dttime.format('DD')]) visitor[dttime.format('YYYY')][dttime.format('MMM')][[dttime.format('DD')]]=[]
})
//console.log(elt[0].split(' ')[0]+ "####" + moment(elt[0],'DD/MMM/YYYY:hh:mm:ss').format('DD-MM-YYYY h:mm:ss'));
//console.log("EEEE"+moment(previousdt).format('DD/MMM/YYYY:hh:mm:ss') + "hhhhhhh" +moment(dttime).format('DD/MMM/YYYY:hh:mm:ss'))
//console.log(previousdt!=dttime)
if (!visitor[dttime.format('YYYY')][dttime.format('MMM')][dttime.format('DD')].includes(useragent)){
visitor[dttime.format('YYYY')][dttime.format('MMM')][dttime.format('DD')].push(useragent)
}
if (previoususeragent != useragent || parseInt(Math.round(previousdt.toDate().getTime()/100000)) != parseInt(Math.round(dttime.toDate().getTime()/100000))) {
/*console.log("###########################################################");
console.log(`${previousdt.toDate().getTime()} != ${dttime.toDate().getTime()}`);
console.log(moment(previousdt).format('DD/MMM/YYYY:hh:mm:ss') + "hhhhhhh" + moment(dttime).format('DD/MMM/YYYY:hh:mm:ss'))
console.log(`useragent: ${useragent} previoususeragent: ${previoususeragent}`);
*/
stat['visits'][dttime.format('YYYY')][dttime.format('MMM')][[dttime.format('DD')]]+=1
previousdt=dttime;
previoususeragent=useragent;
}else{
//console.log("identique compte pas" )
}
})
Object.keys(visitor).forEach(y=>{
var uniqvisitoryear=[];
Object.keys(visitor[y]).forEach(m=>{
var uniqvisitormonth=[];
Object.keys(visitor[y][m]).forEach(d=>{
uniqvisitormonth = [...uniqvisitormonth, ...visitor[y][m][d]]
stat.visitors[y][m][d] = visitor[y][m][d].length
})
uniqvisitoryear=[...uniqvisitoryear, ...uniqvisitormonth]
stat.visitors[y][m][m]=uniqvisitormonth.length;
})
stat.visitors[y][y]=uniqvisitoryear.length
})
return {status:200, data:stat}
}
Tags.statin2D=(stat,pathfile)=>{
if (stat.status==200){
stat=stat.data
}else {
return stat
}
let csv="type;year;month;day;Number\n\r";
["visits", "visitors"].forEach(ch=>{
Object.keys(stat[ch]).forEach(y=>{
Object.keys(stat[ch][y]).forEach(m=>{
Object.keys(stat[ch][y][m]).forEach(d=>{
csv+=`${ch};${y};${m};${d};${stat[ch][y][m][d]}\n\r`
})
})
})
})
fs.outputFileSync(pathfile,csv);
return {status:200, info:"fileready", moreinfo:pathfile}
}
console.log(Tags.statin2D(Tags.nginxlog('/home/phil/Documents/nginx/presentation.capsthd.access.log'),'/home/phil/Documents/nginx/stat.csv'));
module.exports = Tags;

View File

@@ -11,7 +11,7 @@ const moment = require( 'moment' );
const UUID = require( 'uuid' );
const Outputs = require( './Outputs.js' );
const Pagans = require( './Pagans.js' );
const config = require( '../tribes/townconf.js' );
const config = require( '../tribes/townconf' );
const checkdata = require( `../nationchains/socialworld/contracts/checkdata.js`);
/*
@@ -61,19 +61,19 @@ Tribes.init = () => {
Tribes.create = ( data ) => {
/* data = clientconf.json
{
"tribeid": "apixtribe",
"tribeid": "apxtrib",
"genericpsw": "Trze3aze!",
"website": {
"presentation":"https://www.apixtribe.org",
"webapp": "https://webapp.apixtribe.org"
"presentation":"https://www.apxtrib.org",
"webapp": "https://webapp.apxtrib.org"
},
"allowedDOMs": ["local.fr", "localhost:9002", "ndda.fr", "apixtribe.org"],
"clientname": "apixtribe",
"allowedDOMs": ["local.fr", "localhost:9002", "ndda.fr", "apxtrib.org"],
"clientname": "apxtrib",
"clientlogo": "",
"geoloc": [],
"useradmin": {PUBKEY:"",EMAIL:"",LOGIN:"adminapixtribe",UUID:"adminapixtribe"},
"useradmin": {PUBKEY:"",EMAIL:"",LOGIN:"adminapxtrib",UUID:"adminapxtrib"},
"smtp": {
"emailFrom": "support@apixtribe.org",
"emailFrom": "support@apxtrib.org",
"emailcc": [],
"service": "gmail",
"auth": {
@@ -90,7 +90,7 @@ Tribes.create = ( data ) => {
"dnsname": a domain name belonging to the client
"subdns": "www", a sub domain subdns.dnsname give a public web access to
"website": { keywebsite:url}, give access to config.tribes/tribeid/www/keywebsite/index.html,
"allowedDOMs": ["local.fr", "localhost:9002", "nnda.fr"], //for CORS, @TODO generate from prévious URL this allow this apixtribe instance to be accessible
"allowedDOMs": ["local.fr", "localhost:9002", "nnda.fr"], //for CORS, @TODO generate from prévious URL this allow this apxtrib instance to be accessible
"clientname": Name of the organisation if any,
"clientlogo": logo of the organisation if any,
"geoloc": [], if any
@@ -98,7 +98,7 @@ Tribes.create = ( data ) => {
"PUBKEY":public key to be authentify without an email,
"EMAIL":user email, we need at least one of authentification set up after the user can use both or only one
"LOGIN": login to use for access admintribeid,
"UUID": unique id normaly UUID but a uuid admintribeid is the same person in any apixtribe instance so we use it by convention.
"UUID": unique id normaly UUID but a uuid admintribeid is the same person in any apxtrib instance so we use it by convention.
"xlang": lang used by this user
},
"smtp": { smtp used to send email by nodemailer lib basic example with a google account
@@ -134,10 +134,10 @@ Tribes.create = ( data ) => {
}
fs.ensureDirSync( `${config.tribes}/${data.tribeid}` );
[ 'users', 'www', 'referentials', 'nationchains' ].forEach( r => {
fs.copySync( `${config.mainDir}/setup/tribes/apixtribe/${r}`, `${config.tribes}/${data.tribeid}/${r}` );
fs.copySync( `${__base}/setup/tribes/apxtrib/${r}`, `${config.tribes}/${data.tribeid}/${r}` );
} )
fs.outputJsonSync( `${config.tribes}/${data.tribeid}/clientconf.json`, data );
const confcli = JSON.parse( Mustache.render( fs.readFileSync( `${config.mainDir}/setup/tribes/apixtribe/clientconf.mustache`, 'utf8' ), data ) );
const confcli = JSON.parse( Mustache.render( fs.readFileSync( `${__base}/setup/tribes/apxtrib/clientconf.mustache`, 'utf8' ), data ) );
fs.outputJsonSync( `${config.tribes}/${data.tribeid}/clientconf.json`, confcli );
return Pagans.createUser( {
@@ -151,7 +151,7 @@ Tribes.archive = ( tribeid ) => {
// remove tribeid de data ou devdata
try {
fs.moveSync( `${config.tribes}/${tribeid}`, `${config.archivefolder}/${tribeid}` );
//update apixtribeenv
//update apxtribenv
Tribes.init();
return { status: 200, payload: { info: [ 'deletetribeidsuccessfull' ], models: 'Tribes', moreinfo: "TODO see in Tribes.archive" } }
} catch ( err ) {
@@ -279,7 +279,7 @@ Tribes.addspaceweb = ( data ) => {
nginx conf and ssl to serve each https://dnsname to /{tribeid}/www/app/{website}
Carefull this action is executed with root and restart nginx + apixtribe to work
Carefull this action is executed with root and restart nginx + apxtrib to work
*/
data.configdomain = config.tribes;
data.porthttp = config.porthttp;
@@ -293,7 +293,7 @@ Tribes.addspaceweb = ( data ) => {
// add nginx http config
const confnginx = fs.readFileSync( 'setup/nginx/modelwebsite.conf.mustache', 'utf-8' );
fs.outputFileSync( `/etc/nginx/conf.d/${data.dnsname[0]}.conf`, Mustache.render( confnginx, data ), 'utf-8' );
if( data.mode == "dev" ) {
if( data.dns == "unchain" ) {
//add in /etc/hosts
let hosts = fs.readFileSync( '/etc/hosts', 'utf8' );
let chg = false;
@@ -320,14 +320,14 @@ Tribes.addspaceweb = ( data ) => {
clientconf.allowedDOMs = [ ...new Set( ...clientconf.allowedDOMs, ...data.dnsname ) ];
fs.outputJsonSync( `${config.tribes}/${data.tribeid}/clientconf.json`, clientconf, 'utf-8' );
if( !data.setup ) {
// in setup apixtribe is not running and it will be start manually at the 1st run
// in setup apxtrib is not running and it will be start manually at the 1st run
// in other case need to plan a restart for CORS
setTimeout( Tribes.restartapixtribe, 300000, data.clienId );
setTimeout( Tribes.restartapxtrib, 300000, data.clienId );
}
const nginxrestart = execSync( `sudo systemctl restart nginx` )
.toString();
console.log( 'Restart nginx', nginxrestart )
if( data.mode == "prod" ) {
if( data.mode != "unchain" ) {
// get ssl certificate ATTENTION il faut ajouter -d devant chaque domain qui redirige vers l'espace web.
const certbot = execSync( `sudo certbot --nginx -d ${data.dnsname.join(' -d ')}` )
.toString();
@@ -343,7 +343,7 @@ Tribes.addspaceweb = ( data ) => {
}
};
}
Tribes.restartapixtribe = ( tribeid ) => {
Tribes.restartapxtrib = ( tribeid ) => {
console.log( 'A restarting was requested 5mn ago from a new spacedev for ' + tribeid )
execSync( 'yarn restartpm2' );
}

View File

@@ -38,7 +38,7 @@ UploadFiles.addjson = function ( data, header ) {
try {
fs.outputJsonSync( header.destinationfile + '/' + header.filename, data.jsonp );
if( data.callback ) {
const execCB = require( `${config.mainDir}/models/tribeid/${
const execCB = require( `${__base}/models/tribeid/${
header.xworkon
}` );
execCB[ data.callback ]();

4
models/lg/odmdb_en.json Normal file
View File

@@ -0,0 +1,4 @@
{
"schemanotfound":"Schema not found",
"bjectpathnamedoesnotexist":"ObjectPath or objectName does not exist "
}