1
0
forked from apxtri/apxtri
apxtri/apxtri.js
2024-03-23 09:24:01 +01:00

248 lines
8.5 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 cors = require("cors");
const express = require("express");
const process = require("process");
/*******************************************
SEE README.md to have a quick understanding to install a new town
* @param {args} args key:value example node apxtri nationId:ants townId:devfarm dns:devfarm-ants
* if no parameter from adminapi/www/adminapx/conf/setup_xx.json
*
* Keyword townId = "devfarm" then this is unchain town to dev
* else this is a production town ready to chain to the nationId
*
* @returns listen onto http:/dns (80 and 443) for admin webapp and http://localhost:initconf.api.port
* by setting the nginx parameter
* A folder for town data is created at the same level than apxtri as /townId-nationId/conf.json ...
*/
const nam = path.resolve("../..").split("/").slice(-1)[0].split("-");
const town = nam[0];
const nation = nam[1];
const setup=()=>{
const nam = path.resolve("../..").split("/").slice(-1)[0].split("-");
const town = nam[0];
const nation = nam[1];
let setupdone=true
// check nginx exist
if (!fs.existsSync("/etc/nginx/nginx.conf")) {
setupdone=false;
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();
}
if (! (param.dns && param.user) ) {
setupdone=false;
console.log("This is a first install you must run next command with a domain name (use town-nation for dev and the linux user that run apXtri) check ping dns answer and su user exist (check README) \n dns=domainname user=linuxuser yarn dev")
}
return setupdone;
}
const param = {};
argv.slice(2).forEach((arg) => {
const kv = arg.split(":");
if (kv.length == 2) {
param[kv[0]] = kv[1];
}
});
if (!fs.existsSync("../../conf.json")) {
// This is a first install
if (!setup(param)) process.exit();
}
// setup_xx.json is gitignore so at first install we are in dev configuration
/*
let infotown = {
nationId: "ants",
townId: "devfarm",
dns: "devfarm-ants",
comment:
"Auto generate setup from apxtri after node apxtri nationId:value townId:value dns:domaine_to_access",
};
if (fs.existsSync(`${__dirname}/adminapi/www/adminapx/conf/setup_xx.json`)) {
infotown = fs.readJsonSync(
`${__dirname}/adminapi/www/adminapx/conf/setup_xx.json`
);
}
if (
Object.keys(param).length > 0 &&
param.nationId &&
param.townId &&
param.dns
) {
infotown.nationId = param.nationId;
infotown.townId = param.townId;
infotown.dns = param.dns;
}
fs.outputJsonSync(
`${__dirname}/adminapi/www/adminapx/conf/setup_xx.json`,
infotown
);
infotown.dirapi = __dirname;
infotown.dirtown = path.resolve(
`${__dirname}/../${infotown.townId}-${infotown.nationId}`
);
process.env.dirtown = infotown.dirtown;
infotown.dirapxwebapp = path.resolve(`${infotown.dirapi}/..`); //same level as apxtri
if (
!fs.existsSync(`${infotown.dirtown}/conf.json`) ||
!fs.existsSync(`${__dirname}/adminapi/www/nginx_adminapx.conf`)
) {
// Case of new town or request a reset of dns to access adminapx
// genere a minimum conf with nationId, townId, dns, dirapi, dirtown
fs.outputJsonSync(`${infotown.dirtown}/conf.json`, infotown, { space: 2 });
const Towns = require("./api/models/Towns");
const rescreate = Towns.create();
if (rescreate.status != 200) {
console.log("Sorry error ");
process.exit();
}
}
*/
const conf = require(path.resolve(`../../conf.json`));
let doms = conf.dns; // only dns of town during the init process
const currentmod = "apxtri";
const log = conf.api.activelog.includes(currentmod);
// Create and update ./nationchains plutot que cette fonction
// A creuser et voir comment synchro
/*const { updateobjectsfromfreshesttown } = require("./models/Nations.js");
updateobjectsfromfreshesttown(conf.towns, {
pagans: "alias_all.json",
towns: "townId_all.json",
nations: "nationId_all.json",
});
*/
// Run main express process for a /towId-nationId/tribes
let tribelist = {};
if (fs.existsSync(`../../idx/tribeId_all.json`)) {
tribelist = fs.readJsonSync(`../../idx/tribeId_all.json`);
}
let tribeIds = Object.keys(tribelist);
// context is store in tribes/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=[]
tribeIds.forEach((t) => {
tribelist[t].dns.forEach((d) => {
const dm = d.split(".").slice(-2).join(".");
if (!doms.includes(dm)) doms.push(dm);
});
const context={};
const pathtr=path.resolve(`../../${t}`);
context.routes=[]
tribroutes=glob.sync(`${pathtr}/ap*/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}/ap*/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] )
}
})
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));
// To set depending of post put json data size to send
app.use(express.json());
app.use(bodyParser.json(conf.api.bodyparse.json));
app.disable("x-powered-by"); // for security
app.locals.tribeids = tribeIds;
if (log){
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 (log)
console.log(
currentmod,
"request origin:",
req.headers.origin,
"testcors:",
cor, "headers allowed: [", conf.api.exposedHeaders.join(','),"] match with reg:", regtxt
);
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`
);
}
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"
);