const fs = require("fs-extra"); const path = require("path"); const dnsSync = require("dns-sync"); const mustache = require("mustache"); const readlineSync = require("readline-sync"); /** * This Setup is run at the first installation * This is not an exportable module * * * */ const Setup = {}; //const nationsync = require('./Nations').updateChains(); Setup.check = () => { 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" ); process.exit(); } 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("./nationchains/tribes/conf.json")) { console.log( "\x1b[31m Be carefull you already have a town set in ./nationchains/tribes/index.conf.json, check and remove it if you want to setup this town." ); process.exit(); } return true; }; Setup.init = async () => { // Get standard conf and current data const townconf = fs.readJsonSync("./nationchains/www/adminapx/townconf.json"); const apxnations = fs.readJsonSync( `./nationchains/nations/idx/nationId_all.json` ); const apxtowns = fs.readJsonSync(`./nationchains/towns/idx/townId_all.json`); let apxpagans={} if (fs.existsSync(`./nationchains/pagans/idx/alias_all.json`)){ apxpagans = fs.readJsonSync( `./nationchains/pagans/idx/alias_all.json` ); } if (!Object.keys(apxnations).includes(townconf.nationId)) { console.log( `Sorry nationId ${townconf.nationId} does not exist, please change with an existing nation ` ); process.exit(); } if (Object.keys(apxtowns).includes(townconf.townId)) { console.log( `Sorry townId ${townconf.townId} already exist, please change it` ); process.exit(); } /* if (Object.keys(apxpagans).includes(townconf.mayorId)) { console.log( `Sorry paganId ${townconf.maorId} already exist ti create a town you need a new identity, please change it` ); process.exit(); } */ townconf.sudoerUser = process.env.USER; townconf.dirname = path.resolve(`${__dirname}/../../`); // To allow to serve the nation website until the end townconf.nginx.include.push( `${townconf.dirname}/nationchains/www/nginx_*.conf` ); // To allow to serve tribes web site townconf.nginx.include.push( `${townconf.dirname}/nationchains/tribes/*/www/nginx_*.conf` ); townconf.nginx.logs = `${townconf.dirname}/nationchains/logs/nginx`; townconf.nginx.website = "adminapx"; townconf.nginx.fswww = "nationchains/"; //for a local tribe nationchains/tribes/tribeid townconf.nginx.tribeid = "town"; townconf.nginx.pageindex = "index_en.html"; console.log(townconf); if ( !readlineSync.keyInYN( `\x1b[42mThis is the first install from ./nationchains/www/adminapx/townconf.json (check it if you want) \nthis will change your nginx config in /etc/nginx and run nginx from sudoer user ${townconf.sudoerUser} (Yes/no)? \nno if you want to change parameter and run yarn setup again \x1b[0m` ) ) process.exit(); // 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" ); } const tplnginxconf = fs.readFileSync( "./nationchains/www/adminapx/nginx/nginx.conf.mustache", "utf8" ); fs.outputFileSync( "/etc/nginx/nginx.conf", mustache.render(tplnginxconf, townconf), "utf8" ); const tplnginxwww = fs.readFileSync( "./nationchains/www/adminapx/nginx/modelwebsite.conf.mustache", "utf8" ); fs.outputFileSync( `./${townconf.nginx.fswww}www/nginx_${townconf.nginx.website}.conf`, mustache.render(tplnginxwww, townconf), "utf8" ); fs.outputJsonSync("./nationchains/tribes/conf.json", townconf, { spaces: 2, }); //CREATE A TOWN setup local voir utiliser towns.create townconf.town = { townId: townconf.townId, nationId: townconf.nationId, url: `http://${townconf.dns[0]}`, IP: townconf.IP, mayorid: townconf.mayorId, status: "unchain", }; apxtowns[townconf.townId]=townconf.town; fs.outputJsonSync(`./nationchains/towns/idx/townId_all.json`,apxtowns); fs.outputJsonSync(`./nationchains/towns/itm/${townconf.townId}.json`,townconf.town,{spaces:2}); // Create tribe id voir a utiliser tribes.create() townconf.tribe = { tribeId: townconf.tribeId, dns: [], status: "unchain", nationId: townconf.nationId, townId: townconf.townId, }; //tribe does not exist in a new town apxtribes={} apxtribes[townconf.tribeId]=townconf.tribe; fs.outputJsonSync(`./nationchains/tribes/idx/tribeId_all.json`,apxtribes); fs.outputJsonSync(`./nationchains/tribes/itm/${townconf.tribeId}.json`,townconf.tribe,{spaces:2}); fs.ensureDirSync(`./nationchains/tribes/${townconf.tribeId}/logs/nginx`); //CREATE a mayorId pagans if it does not exist if (!apxpagans[townconf.mayorId]){ const Pagans=require('./Pagans'); const createPagans=await Pagans.createId(townconf.mayorId,townconf.passphrase); if (createPagans.status==200){ fs.outputFileSync(`./${townconf.mayorId}_PrivateKey.txt`,createPagans.data.privateKey,"utf8"); fs.outputFileSync(`./${townconf.mayorId}_PublicKey.txt`,createPagans.data.publicKey,"utf8"); console.log(`\x1b[43mCut paste your keys /${townconf.mayorId}_PrivateKey.txt /${townconf.mayorId}_PublicKey.txt \x1b[0m`) }else{ console.log('Error at Pagan creation '); console.log(createPagans); process.exit(); } } //restart nginx const { exec } = require("child_process"); exec(townconf.nginx.restart, (error, stdout, stderr) => { if (error) { console.log("\x1b[42m", error, stdout, stderr, "x1b[0m"); } 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://${townconf.dns}\x1b[0m \x1b[42m \nto finish your town set up. Check README's project to learn more. \x1b[0m\n\x1b[42m###########################################################################################\x1b[0m` ); } }); }; Setup.Checkjson = (conf) => { var rep = ""; const nation_town = fs.readJsonSync( "./nationchains/socialworld/objects/towns/searchindex/towns_nation_uuid.json" ); if (!ObjectKeys(nation_town).includes(conf.nationId)) { rep += `your nationId ${conf.nationId} does not exist you have to choose an existing one`; } if (nation_town[conf.nationId].includes(conf.townId)) { rep += `This conf.townId already exist you have to find a unique town name per nation`; } const getnation = Odmdb.get( "./nationchains/socialworld/objects", "towns", [conf.NationId], [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.sudoerUser}`)) { rep += `/home/${conf.sudoerUser} does not exist, user has to be create with a /home on this server\n`; } 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.dns != "unchain" && !dnsSync.resolve(`${conf.townId}.${conf.nationId}.${conf.dns}`) ) { rep += `\nresolving $${conf.townId}.${conf.nationId}.${conf.dns} will not responding valid IP, please setup domain redirection IP before runing this script`; } return rep; }; Setup.config = (townSetup) => { // Init this instance with a .config.js Setup.configjs(townSetup); // Create tribeid space + a user admin + webspace withe apxtrib webapp install Setup.druidid(townSetup); }; Setup.configjs = (townSetup) => { // Set /config.js 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:", confapxtrib ); console.log("for data :", townSetup); process.exit(); } }; 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}/${townSetup.druidid}`); fs.ensureDirSync(`${config.tribes}/${townSetup.druidid}`); ["users", "www", "referentials", "nationchains"].forEach((r) => { fs.copySync( `${__base}/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 ) ); 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("./Tribes.js"); const access = { app: {}, data: {} }; access.app[`${townSetup.druidid}:webapp`] = "admin"; access.data[townSetup.druidid] = { users: "CRUDO", referentials: "CRUDO", www: "CRUDO", }; const createclient = Tribes.create({ tribeid: townSetup.druidid, genericpsw: townSetup.genericpsw, lanquageReferential: townSetup.language, useradmin: { LOGIN: townSetup.login, xlang: townSetup.language[0], ACCESSRIGHTS: access, }, }); if (createclient.status == 200) { 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, 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: [`${townSetup.subdomain}.${townSetup.domain}`], mode: townSetup.mode, tribeid: townSetup.druidid, website: "webapp", pageindex: "app_index_fr.html", }); if (addspaceweb.status == 200) { console.log(`WELL DONE run yarn dev to test then yarn startpm2 `); } } else { console.log("Issue ", createclient); } }; if (Setup.check()) Setup.init();