adminapi/apxtri/apxtri.js
2024-11-01 07:04:37 +01:00

310 lines
11 KiB
JavaScript
Executable File

//const { argv } = require("process");
const fs = require("fs-extra");
//const mustache = require("mustache");
const bodyParser = require("body-parser");
const glob = require("glob");
const path = require("path");
const Mustache = require("mustache");
const cors = require("cors");
const express = require("express");
const process = require("process");
/*******************************************
SEE README.md to start
********************************************/
const apxtri = {};
apxtri.main = async () => {
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, install then rerun yarn command."
);
process.exit(0);
}
//console.log(path.resolve("../adminapi/objects/tribes/itm/adminapi.json"))
if (
fs.existsSync("../adminapi/objects/tribes/idx/tribes_dns.json") &&
fs.existsSync("../adminapi/objects/tribes/itm/adminapi.json")
) {
apxtri.runexpress(
fs.readJsonSync(`../adminapi/objects/tribes/idx/tribes_dns.json`),
fs.readJSONSync("../adminapi/objects/tribes/itm/adminapi.json")
);
} else {
await apxtri.setup();
}
};
apxtri.setup = async () => {
console.log("Warning, this is a first install");
const initadminapi = fs.readJsonSync(
"../adminapi/apxtri/setup/initadminapi.json"
);
try {
initadminapi.townpath = __dirname.replace("/adminapi/apxtri", "");
const townnation = initadminapi.townpath.split("/").slice(-1)[0].split("-");
initadminapi.townId = townnation[0];
initadminapi.nationId = townnation[1];
} catch (err) {
console.log("Your town folder must be something townid-nation");
}
initadminapi.sudoUser = process.env.USER;
// Loop in initadminapi.urlinit until one answer
/*const headers = {
xtrkversion: 1,
xtribe: "adminapi",
xapp: "apx",
xlang: "fr",
xalias: "anonymous",
xhash: "anonymous",
xdays: 0,
xuuid: "0",
};
// add in crontab each day
// find /home/phil/apxtowns/dev-ants/adminapi/objects -type d -name "nations" -o -name "towns" -o -name "pagans" -o -name "tplstring" -o -name "wwws" | tar -cvzf /home/phil/dev-ants/adminapi/objects/wwws/cdn/share/setupobjects.tar.gz
for (url of initadminapi.urlinit) {
if (!fs.existsSync("../objects/nations")) {
const urlinit = `${url}/api/adminapi/wwws/updatelocaldbanonymous/adminapi/apx/blockchain/0`;
const getdata = await fetch(urlinit, { headers: headers });
console.log(getdata)
if (getdata.ok) { {
"name": "tribes_dns",
"keyval": "tribeId",
"type": "view",
"objkey": [
"dns"
],
"filter": ""
}
const data = await getdata.json();
console.log(Object.keys(data.data.itms));
Object.keys(data.data.itms).forEach((o) => {
//idxname contain the real name of the index to use
fs.outputJSONSync(
`../objects/${o}/idx/${initadminapi.idxname[o]}s.json`,
data.data.itms[o]
);
// save each itm to init data
Object.keys(data.data.itms[o]).forEach((i) => {
fs.outputJSONSync(
`../objects/${o}/itms/${i}.json`,
data.data.itms[o][i]
);
});
});
}
}
}*/
//check nation exist and town does not exist
if (
!fs.existsSync("../adminapi/objects/nations/idx/lst_nations.json") ||
!fs.existsSync("../adminapi/objects/towns/idx/lst_towns.json")
) {
console.log(
`Sorry, check setup.sh process that was not able to init your adminapi/objects `
);
process.exit(0);
}
fs.outputJSONSync(
"../adminapi/objects/tribes/itm/adminapi.json",
initadminapi,
{ space: 2 }
);
fs.outputJSONSync("../adminapi/objects/tribes/conf.json", {
name: "tribes",
schema: "adminapi/schema/tribes.json",
lastupdate: 0,
});
fs.outputJSONSync("../adminapi/objects/tribes/idx/lst_tribeId.json", [
"adminapi",
]);
fs.outputJSONSync("../adminapi/objects/tribes/idx/tribes_dns.json", {
adminapi: initadminapi.dns,
});
const idxadminapi = {
adminapi: {
tribeId: "adminapi",
dns: initadminapi.dns,
status: initadminapi.status,
nationId: initadminapi.nationId,
townId: initadminapi.townId,
},
};
fs.outputJSONSync("../adminapi/objects/tribes/idx/tribes.json", idxadminapi, {
space: 2,
});
// check nginx conf and eventually change if not starting by user "current user";
let etcnginx = fs.readFileSync("/etc/nginx/nginx.conf", "utf8");
if (etcnginx.split("\n")[0] !== `user ${initadminapi.sudoUser};`) {
const nginxmain = fs.readFileSync("../adminapi/apxtri/setup/nginx.maincf");
console.log("Modify /etc/nginx/nginx.conf");
fs.outputFileSync(
"/etc/nginx/nginx.conf",
Mustache.render(nginxmain, initadminapi),
{ adAdmin: true }
);
}
// add conf for http://adminapx.adminapi
const nginxapx = fs.readFileSync(
"../adminapi/apxtri/setup/nginx.wwwscf",
"utf8"
);
initadminapi.website="adminapx";
fs.outputFileSync(
`../adminapi/nginx/adminapx.adminapi.conf`,
Mustache.render(nginxapx, initadminapi)
);
// add hosts entry for local access
// this command is ran by the setup.sh
// sudo sed -i '/127.0.0.1 adminapx.adminapi/c\127.0.0.1 adminapx.adminapi' /etc/hosts
const { exec } = require("child_process");
exec(initadminapi.nginx.restart, (error, stdout, stderr) => {
if (error) {
console.log("\x1b[42m", error, stdout, stderr, "x1b[0m");
process.exit(0);
} else {
console.log(
`\x1b[42m###################################################################\x1b[0m\n\x1b[42mWellcome into apxtri, 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://apx.adminapî\x1b[0m \x1b[42m \n\x1b[0m\n\x1b[42m###########################################################################################\x1b[0m`
);
}
});
apxtri.runexpress(
fs.readJsonSync(`../adminapi/objects/tribes/idx/tribes_dns.json`),
fs.readJSONSync("../adminapi/objects/tribes/itm/adminapi.json")
);
};
apxtri.runexpress = async (tribesdns, conf) => {
const Odmdb = require(path.resolve("./apxtri/models/Odmdb.js"));
let tribeIds = Object.keys(tribesdns);
// context is store in /itm/tribename.json ={contexte:{routes:[],models:[{model:,tplstringslg:[]}]}
// routes={url,route} check how to add plugin tribe route later
// keep only the 2 last part (.) of domain name to validate cors with it (generic domain)
let routes = [];
let doms = [];
tribeIds.forEach((t) => {
tribesdns[t].forEach((d) => {
const dm = d.split(".").slice(-2).join(".");
if (!doms.includes(dm)) doms.push(dm);
//reindex database attention check dev-ants/.. a bug was fixed
glob.sync(`../${t}/objects/*`).forEach((o) => {
console.log(t, o);
Odmdb.runidx(o);
});
});
const context = {};
const pathtr = path.resolve(`../${t}`);
context.routes = [];
tribroutes = glob.sync(`${pathtr}/apxtri/routes/*.js`).map((f) => {
const rt = `/${t}/${path.basename(f, ".js")}`;
context.routes.push(rt);
return { url: rt, route: f };
});
context.models = glob.sync(`${pathtr}/apxtri/models/*.js`).map((f) => {
const modname = `${path.basename(f, ".js")}`;
return {
model: modname,
tplstrings: glob
.sync(`${pathtr}/objects/tplstrings/${modname}_*.json`)
.map((l) => path.basename(l, ".json").split("_")[1]),
};
});
console.log(context.routes);
console.log(context.models);
//const conft = `../itm/${t}.json`;
//const ctx = fs.readJsonSync(conft);
//ctx.context = context;
//fs.outputJSONSync(conft, ctx, { spaces: 2 });
routes = routes.concat(tribroutes);
});
const app = express();
// load express parameter from conf
Object.keys(conf.api.appset).forEach((p) => {
app.set(p, conf.api.appset[p]);
});
// To set depending of data form or get size to send
app.use(bodyParser.urlencoded(conf.api.bodyparse.urlencoded));
app.use(bodyParser.json(conf.api.bodyparse.json));
// To set depending of post put json data size to send
app.use(express.json(conf.api.json));
app.disable("x-powered-by"); // for security
app.locals.tribeids = tribeIds;
const currentmod = "Odmdb";
const log = conf.api.activelog
? conf.api.activelog.includes(currentmod)
: false;
console.log(
currentmod,
" Allowed DOMs to access to this apxtri server:",
JSON.stringify(doms)
);
console.log(currentmod, " app.locals.tribeids", app.locals.tribeids);
// Cors management
let originlst = "test";
doms.forEach((d) => {
originlst += `|${d.replace(/\./g, "\\.")}`;
});
const regtxt = `^http.?:\/\/(${originlst})`;
let cor = false;
const regorigin = new RegExp(regtxt);
app.use((req, res, next) => {
if (req.headers.origin == undefined) {
cor = true;
} else {
cor = regorigin.test(req.headers.origin);
}
if (!cor)
console.log(
`The domain name ${req.headers.origin} is not allow to access for CORS settings, add it in itm/tribename.json in dns`
);
cors({
origin: cor,
allowedHeaders: conf.api.exposedHeaders,
exposedHeaders: conf.api.exposedHeaders,
credentials: true,
preflightContinue: false,
optionsSuccessStatus: 204,
});
next();
});
// Routers add any routes from /routes and /plugins
let logroute = "Routes available on this apxtri instance: \n";
routes.forEach((r) => {
try {
logroute += r.url.padEnd(30, " ") + r.route + "\n";
app.use(r.url, require(r.route));
} catch (err) {
logroute += " (err check it module.exports=router;? or ...)\n======\n ";
console.log("raise err-:", err);
}
});
if (log) {
console.log(currentmod, logroute);
if (process.env.NODE_MODE == "dev")
console.log(
`\x1b[42m############################################################################################\x1b[0m\n\x1b[42mThis is dev conf accessible in http://dev-ants to switch this as production, you must run:\n 1 - 'yarn dev nationId:ants townId:dev dns:dev-ants' to conf your town and check it.\n 2 - 'yarn startpm2'\n Where:\n\x1b[42m * nationId have to exist in the nationchains\n * townId new or if exist must have the same current dns,\n * dns domaine that has to redirect 80/443 into this server.\n Check README's project to learn more.\x1b[0m\n To work with apxweb for the front use http://dev-ants/apxwebapp/www/websitename/src/index.html to use the api during dev process\n\x1b[42m############################################################################################\x1b[0m`
);
}
//Listen event file for each tribe
// @TODO à ajouter ici
app.listen(conf.api.port, () => {
let webaccess = `api waits request on port:${conf.api.port} for`;
conf.dns.forEach((u) => {
webaccess += `${u}/api/ `;
});
if (log) console.log(currentmod, webaccess);
});
console.log(
"\x1b[42m\x1b[37m",
"Made with love for people's freedom, enjoy !!!",
"\x1b[0m"
);
};
apxtri.main();