This commit is contained in:
2023-05-16 10:31:27 +02:00
parent 433fe035b9
commit 85862577b2
160 changed files with 268 additions and 202 deletions

View File

@@ -3,7 +3,7 @@ const glob = require( 'glob' );
const moment = require( 'moment' );
const axios = require( 'axios' );
const conf=require('../../nationchains/tribes/conf.json')
const conf=require(`${process.env.dirtown}/conf.json`)
/*
Model that will process actions plan for each client like sending email campain, or anything that

View File

@@ -4,7 +4,7 @@ const glob = require("glob");
const jwt = require("jwt-simple");
const axios = require("axios");
const path=require('path');
const conf=require('../../nationchains/tribes/conf.json')
const conf=require(`${process.env.dirtown}/conf.json`);
const Odmdb = require('./Odmdb.js');
// lowercase 1st letter is normal
const towns = require('./Towns.js');
@@ -34,18 +34,18 @@ Nations.updateChains = async (newtown) =>{
*/
const res= {status:400};
const ref2update={}
glob.sync('nationchains/**/idx/conf.json').forEach(f=>{
glob.sync(`${__dirapi}nationchains/**/idx/conf.json`).forEach(f=>{
const ref=fs.readJsonSync(f)
ref2update[path.basename(ref.schema,'.json')]=ref.lastupdate;
})
console.log(ref2update)
// Get list of town to check n of them have fresh update
const knowntowns =fs.readJsonSync('nationchains/towns/idx/towns_townId_all.json');
const knowntowns =fs.readJsonSync(`${__dirapi}nationchains/towns/idx/towns_townId_all.json`);
let promiselistblock=[]
let towidlist=[]
Object.keys(knowntowns).forEach(townid=>{
// identify the town with the highest block to update town
promiselistblock.push(axios.get(`${knowntowns[townid].url}/blocks/idx/conf.json`));
promiselistblock.push(axios.get(`https://${knowntowns[townid].url}/blocks/idx/conf.json`));
townidlistblock.push(townid)
});
let selectedtown=""

View File

@@ -2,7 +2,7 @@ const glob = require("glob");
const path = require("path");
const fs = require("fs-extra");
const axios = require('axios');
const conf=require('../../nationchains/tribes/conf.json')
const conf=require(`${process.env.dirtown}/conf.json`)
const Checkjson = require(`./Checkjson.js`);
/* This manage Objects for indexing and check and act to CRUD

View File

@@ -4,10 +4,11 @@ const dayjs = require("dayjs");
const fs = require("fs-extra");
const axios = require("axios");
const openpgp = require("openpgp");
var conf = {};
if (fs.existsSync("../../nationchains/tribes/conf.json")) {
/*if (fs.existsSync("../../nationchains/tribes/conf.json")) {
conf = require("../../nationchains/tribes/conf.json");
}
}*/
const conf = require(`${process.env.dirtown}/conf.json`);
console.log(conf);
/**
* Pagan Management numeric Identity and Person (Person = Pagan Id + tribe)
@@ -27,17 +28,17 @@ Pagans.create = (alias, publicKey) => {
* @todo use Odmdb to add a pagan
*/
let apxpagans = {};
if (fs.existsSync(`${__base}nationchains/pagans/idx/alias_all.json`)) {
if (fs.existsSync(`${__dirapi}/nationchains/pagans/idx/alias_all.json`)) {
apxpagans = fs.readJsonSync(
`${__base}nationchains/pagans/idx/alias_all.json`
`${__dirapi}/nationchains/pagans/idx/alias_all.json`
);
}
apxpagans[alias] = { alias, publicKey };
fs.outputJsonSync(
`${__base}nationchains/pagans/idx/alias_all.json`,
`${conf.dirapi}/nationchains/pagans/idx/alias_all.json`,
apxpagans
);
fs.outputJsonSync(`${__base}nationchains/pagans/itm/${alias}.json`, {
fs.outputJsonSync(`${conf.dirapi}/nationchains/pagans/itm/${alias}.json`, {
alias,
publicKey,
});
@@ -57,20 +58,20 @@ Pagans.personupdate = (alias, tribe, persondata) => {
dt_create: dayjs(),
accessrights: { profil: "user" },
};
if (fs.existsSync(`${__base}tribes/${tribe}/person/itm/${alias}.json`)) {
if (fs.existsSync(`${process.env.dirtown}/tribes/${tribe}/person/itm/${alias}.json`)) {
person = fs.readJsonSync(
`${__base}tribes/${tribe}/person/itm/${alias}.json`
`${process.env.dirtown}/tribes/${tribe}/person/itm/${alias}.json`
);
person.dt_update = dayjs();
}
Object.keys(persondata).forEach((d) => {
person[d] = persondata[d];
});
//const checkjson= Checkjson.schema.data = (fs.readJsonSync(`${__base}}nationchains/schema/person.json`, person, false)
//const checkjson= Checkjson.schema.data = (fs.readJsonSync(`${conf.dirapi}/nationchains/schema/person.json`, person, false)
// if checkjson.status==200 create /update with odmdb to update index data
// see odmdb that did all and return standard message
fs.outputJSONSync(
`${__base}tribes/${tribe}/person/itm/${alias}.json`,
`${process.env.dirtown}/tribes/${tribe}/person/itm/${alias}.json`,
person,
{
space: 2,

View File

@@ -1,3 +1,4 @@
const { argv } = require('process');
const fs = require("fs-extra");
const path = require("path");
const dnsSync = require("dns-sync");
@@ -5,6 +6,7 @@ const mustache = require("mustache");
const readlineSync = require("readline-sync");
const Wwws = require("../models/Wwws.js");
const Nations = require("../models/Nations.js");
/**
* This Setup is run at the first installation
* This is not an exportable module
@@ -16,7 +18,35 @@ const Wwws = require("../models/Wwws.js");
const Setup = {};
//const nationsync = require('./Nations').updateChains();
Setup.check = () => {
Setup.check = (param) => {
//run a nationchains sync nd check town does not already exist
["nationId","townId","url"].forEach(k=>{
if (!param[k]){
console.log(`Please provide a ${k} in your param`)
process.exit();
}
})
const initconf = fs.readJsonSync('./adminapi/www/adminapx/tpldata/initconf.json')
let nationupdated=false;
for (let t=0; t<initconf.towns;t++){
const synchro = Nations.synchronize(initconf.towns[t].url)
if (synchro.status==200){
nationupdated=true;
break;}
}
if (!nationupdated){
Console.log('Please check your internet access other towns cannot be reach to synchronize your town')
process.exit();
}
// check nationId exist and townId not
if (!Object.keys(fs.readJsonSync('../../nationchains/nations/idx/nationId_all.json')).includes(param.nationId) {
console.log(`Sorry your nationId: ${param.nationId} does not exist`);
process.exit();
}
if (Object.keys(fs.readJsonSync('../../nationchains/towns/idx/townId_all.json')).includes(param.townId) {
console.log(`Sorry your townId: ${param.townId} already exist, please choose another one`);
process.exit();
}
if ("testinternet" != "testinternet") {
console.log(
"\x1b[31m Check your internet access, to setup this town we need to update the Nations. It seems we cannot do it"
@@ -29,16 +59,16 @@ Setup.check = () => {
);
process.exit();
}
if (fs.existsSync("./nationchains/www/nginx_adminapx.conf")) {
if (fs.existsSync("./adminapi/www/nginx_adminapx.conf")) {
console.log(
"\x1b[31m Be carefull you already have a town set, check http://adminapx or remove ./nationchains/www/nginx_adminapx.conf to reset a sync with the last nationchains"
"\x1b[31m Be carefull you already have a town set, check http://adminapx or remove ./adminapi/www/nginx_adminapx.conf to reset nginxconf"
);
process.exit();
}
return true;
};
Setup.init = async () => {
Setup.init = async (param) => {
/**
* create empty nationchains
* rsync all subfolder nationchains except the tribes/ and /www/nginx_adminapx.conf
@@ -46,29 +76,77 @@ Setup.init = async () => {
* Then to send new version we fix a master production
*
*/
const initconf = fs.readJSONSync(
"./nationchains/www/adminapx/static/tpldata/initconf.json"
);
const initconf = fs.readJsonSync('./adminapi/www/adminapx/tpldata/initconf.json')
initconf.sudoerUser = process.env.USER;
initconf.dirname = path.resolve(`${__dirname}/../../`);
initconf.dirapi = path.resolve(`${__dirname}/../../`);
initconf.dirtown = path.resolve(`${__dirname}/../../../${param.townId}-${param.nationId}/`)
// To allow to serve the nation website until the end
initconf.nginx.include.push(
`${townconf.dirname}/nationchains/www/nginx_*.conf`
`${initconf.dirapi}/adminapi/www/nginx_*.conf`
);
// To allow to serve tribes web site
initconf.nginx.include.push(
`${townconf.dirname}/nationchains/tribes/*/www/nginx_*.conf`
`${initconf.dirtown}/tribes/*/www/nginx_*.conf`
);
initconf.nginx.logs = `${townconf.dirname}/nationchains/logs/nginx`;
initconf.dns.push(param.url)
initconf.nginx.logs = `${dirtown}/logs/nginx/adminapx`;
initconf.nginx.website = "adminapx";
initconf.nginx.fswww = "nationchains/"; //for a local tribe nationchains/tribes/tribeid
initconf.nginx.tribeid = "town";
initconf.nginx.fswww = `${dirapi}/adminapi/www`;
initconf.nginx.pageindex = "index_en.html";
const nginxconf = Wwws.apxtribinstall(initconf);
if (nginxconf.status == 200) {
const nginxconf = fs.readFileSync(
"../../adminapi/www/adminapx/static/tpl/nginx.conf.mustache",
"utf8"
);
const proxyparams = fs.readFileSync(
"../../adminapi/www/adminapx/static/tpl/nginxproxy_params.mustache",
"utf8"
);
// saved and change nginx conf
if (!fs.existsSync("/etc/nginx/nginxconf.saved")) {
fs.moveSync("/etc/nginx/nginx.conf", "/etc/nginx/nginxconf.saved");
console.log(
"your previous /etc/nginx/nginx.conf was backup in /etc/nginx/nginxconf.saved"
);
}
fs.outputFileSync(
"/etc/nginx/nginx.conf",
mustache.render(nginxconf, initconf),
"utf8"
);
fs.outputFileSync(
"/etc/nginx/proxy_params",
mustache.render(proxyparams, initconf),
"utf8"
);
if (!fs.existsSync(initconf.nginx.logs)) fs.mkdirSync(initconf.nginx.logs);
const { exec } = require("child_process");
exec(.restart, (error, stdout, stderr) => {
if (error) {
console.log("\x1b[42m", error, stdout, stderr, "x1b[0m");
//@todo supprimer la derniere config et relancer
} else {
console.log(
`\x1b[42m###########################################################################################\x1b[0m\n\x1b[42mWellcome into apxtrib, you can now 'yarn dev' for dev or 'yarn startpm2' for prod or \n'yarn unittest' for testing purpose. Access to your town here \x1b[0m\x1b[32mhttp://${param.url}\x1b[0m \x1b[42m \nto finish your town setup. Don't forget to set your localhost /etc/hosts by adding 127.0.0.1 adminapx or {LAN IP} adminapx . Check README's project to learn more. \x1b[0m\n\x1b[42m###########################################################################################\x1b[0m`
);
}
};
if (Setup.check()) Setup.init();
if (argv.length!=5) {
console.log("Check you parameter you need to type yarn setup nationId:ants townid:mytown url:mytown-ants ")
process.exit()
}
const param={};
argv.slice(2).forEach(arg=>{
const kv=arg.split(':')
if (kv.length==2){
param[kv[0]]=kv[1]
}else{
console.log('Check your args that have to be yarn main key1:val1 keyn:valn');
process.exit(1);
}
})
if (Setup.check(param)) Setup.init(param);
// After testing remove all stuff after this line
@@ -106,16 +184,16 @@ Setup.initold = async () => {
}
*/
townconf.sudoerUser = process.env.USER;
townconf.dirname = path.resolve(`${__dirname}/../../`);
townconf.dirapi = path.resolve(`${__dirname}/../../`);
// To allow to serve the nation website until the end
townconf.nginx.include.push(
`${townconf.dirname}/nationchains/www/nginx_*.conf`
`${townconf.dirapi}/nationchains/www/nginx_*.conf`
);
// To allow to serve tribes web site
townconf.nginx.include.push(
`${townconf.dirname}/nationchains/tribes/*/www/nginx_*.conf`
`${townconf.dirapi}/nationchains/tribes/*/www/nginx_*.conf`
);
townconf.nginx.logs = `${townconf.dirname}/nationchains/logs/nginx`;
townconf.nginx.logs = `${townconf.dirapi}/nationchains/logs/nginx`;
townconf.nginx.website = "adminapx";
townconf.nginx.fswww = "nationchains/"; //for a local tribe nationchains/tribes/tribeid
townconf.nginx.tribeid = "town";
@@ -333,11 +411,11 @@ Setup.druidid = (townSetup) => {
fs.ensureDirSync(`${config.tribes}/${townSetup.druidid}`);
["users", "www", "referentials", "nationchains"].forEach((r) => {
fs.copySync(
`${__base}/setup/tribes/apxtrib/${r}`,
`${__dirapi}/setup/tribes/apxtrib/${r}`,
`${config.tribes}/${townSetup.druidid}/${r}`
);
});
/* const confcli = JSON.parse( Mustache.render( fs.readFileSync( `${__base}/setup/tribes/apxtrib/clientconf.mustache`, 'utf8' ), townSetup ) );
/* const confcli = JSON.parse( Mustache.render( fs.readFileSync( `${__dirapi}/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
@@ -392,4 +470,3 @@ Setup.druidid = (townSetup) => {
}
};
if (Setup.check()) Setup.init();

View File

@@ -4,7 +4,7 @@ const glob = require( 'glob' );
const moment = require( 'moment' );
const jwt = require( 'jwt-simple' );
const UUID = require( 'uuid' );
const conf=require('../../nationchains/tribes/conf.json')
const conf=require(`${process.env.dirtown}/conf.json`)
const Checkjson = require( `./Checkjson.js`);
const Towns = {};

View File

@@ -10,7 +10,7 @@ const jwt = require( 'jwt-simple' );
const moment = require( 'moment' );
const UUID = require( 'uuid' );
const Pagans = require( './Pagans.js' );
const config = require( '../../nationchains/tribes/conf.json' );
const conf = require( `${process.env.dirtown}/conf.json`);
const Checkjson = require( `./Checkjson.js`);
/*
tribeid manager
@@ -33,14 +33,14 @@ Tribes.init = () => {
} );
let DOMs = [];
let appname = {};
TribesGlobalConfig = glob.sync( `${config.tribes}/**/clientconf.json` )
TribesGlobalConfig = glob.sync( `${conf.tribes}/**/clientconf.json` )
.map( f => {
const conf = fs.readJSONSync( f );
// check if plugins exist and add it in .plugins of each tribeid conf
conf.plugins = glob.sync( `${config.tribes}/${conf.tribeid}/plugins/**/package.json` )
conf.plugins = glob.sync( `${conf.tribes}/${conf.tribeid}/plugins/**/package.json` )
.map( p => {
const pack = fs.readJsonSync( p, 'utf8' );
routes.push( { url: `/${pack.name}`, route: `${config.tribes}/${conf.tribeid}/plugins/${pack.name}/route.js` } );
routes.push( { url: `/${pack.name}`, route: `${conf.tribes}/${conf.tribeid}/plugins/${pack.name}/route.js` } );
return pack;
} );
//Add here any other info to get a global view and init
@@ -50,8 +50,8 @@ Tribes.init = () => {
if( conf.website ) appname[ conf.tribeid ] = Object.keys( conf.website )
return conf;
} );
// store global conf fofs.existsSync( `${config.tmp}/clientconfglob.json` )r sharing to other api
fs.outputJsonSync( `${config.tmp}/clientconfglob.json`, TribesGlobalConfig, {
// store global conf fofs.existsSync( `${conf.tmp}/clientconfglob.json` )r sharing to other api
fs.outputJsonSync( `${conf.tmp}/clientconfglob.json`, TribesGlobalConfig, {
spaces: 2
} );
return { tribeids, routes, DOMs, appname }
@@ -87,7 +87,7 @@ Tribes.create = ( data ) => {
"genericpsw": a generic password for new user need upper lowercase number ans special char
"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,
"website": { keywebsite:url}, give access to conf.tribes/tribeid/www/keywebsite/index.html,
"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,
@@ -123,20 +123,20 @@ Tribes.create = ( data ) => {
}
//loginsglob = {login:tribeid}
let loginsglob = {};
if( fs.existsSync( `${config.tmp}/loginsglob.json`, 'utf-8' ) ) {
loginsglob = fs.readJsonSync( `${config.tmp}/loginsglob.json`, 'utf-8' );
if( fs.existsSync( `${conf.tmp}/loginsglob.json`, 'utf-8' ) ) {
loginsglob = fs.readJsonSync( `${conf.tmp}/loginsglob.json`, 'utf-8' );
}
const logins = Object.keys( loginsglob );
if( logins.includes( data.useradmin.login ) ) {
return { status: 403, payload: { model: "client", info: [ 'loginalreadyexist' ] } }
}
fs.ensureDirSync( `${config.tribes}/${data.tribeid}` );
fs.ensureDirSync( `${conf.tribes}/${data.tribeid}` );
[ 'users', 'www', 'referentials', 'nationchains' ].forEach( r => {
fs.copySync( `${__base}/setup/tribes/apxtrib/${r}`, `${config.tribes}/${data.tribeid}/${r}` );
fs.copySync( `${__dirapi}/setup/tribes/apxtrib/${r}`, `${conf.tribes}/${data.tribeid}/${r}` );
} )
fs.outputJsonSync( `${config.tribes}/${data.tribeid}/clientconf.json`, 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 );
fs.outputJsonSync( `${conf.tribes}/${data.tribeid}/clientconf.json`, data );
const confcli = JSON.parse( Mustache.render( fs.readFileSync( `${__dirapi}/setup/tribes/apxtrib/clientconf.mustache`, 'utf8' ), data ) );
fs.outputJsonSync( `${conf.tribes}/${data.tribeid}/clientconf.json`, confcli );
return Pagans.createUser( {
xpaganid: "setup",
@@ -148,7 +148,7 @@ Tribes.archive = ( tribeid ) => {
//A faire zip un repertoire tribeid dans
// remove tribeid de data ou devdata
try {
fs.moveSync( `${config.tribes}/${tribeid}`, `${config.archivefolder}/${tribeid}` );
fs.moveSync( `${conf.tribes}/${tribeid}`, `${conf.archivefolder}/${tribeid}` );
//update apxtribenv
Tribes.init();
return { status: 200, payload: { info: [ 'deletetribeidsuccessfull' ], models: 'Tribes', moreinfo: "TODO see in Tribes.archive" } }
@@ -178,7 +178,7 @@ Tribes.checkaccessfiles = ( listfile, typeaccessrequested, useraccessrights, use
let done;
for( const f of listfile ) {
done = false;
if( !fs.existsSync( `${config.tribes}/${f}` ) ) {
if( !fs.existsSync( `${conf.tribes}/${f}` ) ) {
done = true;
checkauthlistfile.ko.push( f )
console.log( `${f} file does not exist` )
@@ -195,8 +195,8 @@ Tribes.checkaccessfiles = ( listfile, typeaccessrequested, useraccessrights, use
} else {
// check if in folder we have a.info.json .file[f].shared{useruuid:'CRUDO'}
console.log( 'structf', structf )
if( fs.existsSync( `${config.tribes}/${structf.slice(0,-1).join('/')}/.info.json` ) ) {
inforep = fs.readJsonSync( `${config.tribes}/${structf.slice(0,-1).join('/')}/.info.json`, 'utf8' )
if( fs.existsSync( `${conf.tribes}/${structf.slice(0,-1).join('/')}/.info.json` ) ) {
inforep = fs.readJsonSync( `${conf.tribes}/${structf.slice(0,-1).join('/')}/.info.json`, 'utf8' )
}
console.log( `no accessrights for ${f} for ${useruuid} ` )
}
@@ -218,12 +218,12 @@ Tribes.dirls = ( tribeid, dir ) => {
Return list of file into tribeid/dir
*/
let comment = { src: `${tribeid}/${dir}`, file: {}, dir: {} };
if( fs.existsSync( `${config.tribes}/${tribeid}/${dir}/.info.json` ) ) {
comment = fs.readJsonSync( `${config.tribes}/${tribeid}/${dir}/.info.json`, 'utf-8' );
if( fs.existsSync( `${conf.tribes}/${tribeid}/${dir}/.info.json` ) ) {
comment = fs.readJsonSync( `${conf.tribes}/${tribeid}/${dir}/.info.json`, 'utf-8' );
}
const listfile = []
const listdir = []
glob.sync( `${config.tribes}/${tribeid}/${dir}/*` )
glob.sync( `${conf.tribes}/${tribeid}/${dir}/*` )
.forEach( f => {
//console.log( f )
const stats = fs.statSync( f );
@@ -259,7 +259,7 @@ Tribes.dirls = ( tribeid, dir ) => {
if( !listdir.includes( d ) ) delete comment.dir[ d ]
} )
//console.log( comment )
fs.outputJson( `${config.tribes}/${tribeid}/${dir}/.info.json`, comment, 'utf-8' );
fs.outputJson( `${conf.tribes}/${tribeid}/${dir}/.info.json`, comment, 'utf-8' );
return { status: 200, payload: { info: [ 'succestogetls' ], models: 'Tribes', moreinfo: comment } }
};
Tribes.addspaceweb = ( data ) => {
@@ -279,15 +279,15 @@ Tribes.addspaceweb = ( data ) => {
Carefull this action is executed with root and restart nginx + apxtrib to work
*/
data.configdomain = config.tribes;
data.porthttp = config.porthttp;
console.assert( config.loglevel == "quiet", 'data to create spaceweb:', data );
data.configdomain = conf.tribes;
data.porthttp = conf.porthttp;
console.assert( conf.loglevel == "quiet", 'data to create spaceweb:', data );
// create spaceweb app for tribeid/www/app/website/pageindexname.html
if( !fs.existsSync( `${config.tribes}/${data.tribeid}/www/app/${data.website}` ) ) {
fs.outputFileSync( `${config.tribes}/${data.tribeid}/www/app/${data.website}/${data.pageindex}`, `<h1>Hello ${data.tribeid} ${data.website} onto ${data.dnsname.join(',')}`, 'utf-8' )
if( !fs.existsSync( `${conf.tribes}/${data.tribeid}/www/app/${data.website}` ) ) {
fs.outputFileSync( `${conf.tribes}/${data.tribeid}/www/app/${data.website}/${data.pageindex}`, `<h1>Hello ${data.tribeid} ${data.website} onto ${data.dnsname.join(',')}`, 'utf-8' )
}
//create logs folder
fs.ensureDirSync( `${config.tribes}/${data.tribeid}/logs/nginx` );
fs.ensureDirSync( `${conf.tribes}/${data.tribeid}/logs/nginx` );
// 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' );
@@ -312,11 +312,11 @@ Tribes.addspaceweb = ( data ) => {
}
} )
//update clienconf.json
const clientconf = fs.readJsonSync( `${config.tribes}/${data.tribeid}/clientconf.json` );
const clientconf = fs.readJsonSync( `${conf.tribes}/${data.tribeid}/clientconf.json` );
clientconf.website[ data.website ] = data.dnsname[ 0 ];
//merge allowedDOMs in unique concat
clientconf.allowedDOMs = [ ...new Set( ...clientconf.allowedDOMs, ...data.dnsname ) ];
fs.outputJsonSync( `${config.tribes}/${data.tribeid}/clientconf.json`, clientconf, 'utf-8' );
fs.outputJsonSync( `${conf.tribes}/${data.tribeid}/clientconf.json`, clientconf, 'utf-8' );
if( !data.setup ) {
// 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