apxtrib/apxtrib.js

155 lines
6.2 KiB
JavaScript
Raw Normal View History

2023-05-12 05:59:32 +00:00
const fs = require("fs-extra");
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");
2023-01-22 09:53:09 +00:00
/*******************************************
2023-03-27 05:52:21 +00:00
SEE https://gitea.ndda.fr/apxtrib/apxtrib/wiki/Devrules
To have a quick understanding and convention before doing deeply in source code
2023-01-22 09:53:09 +00:00
2023-04-27 04:17:20 +00:00
*/
2023-05-12 05:59:32 +00:00
// Global data : add here globale variable that take care between RAM space anf fs access
2023-05-16 08:31:27 +00:00
// to make absolute path with `${__dirapi}relativepath`
//global.__dirapi = __dirname + "/";
2023-05-12 05:59:32 +00:00
// app.locals.tribeids is defined later in apixtrib.js and allow express app to always have in memory a dynamic of tribeId available in req.app.locals.tribeids
2023-01-22 09:53:09 +00:00
// check setup
2023-05-16 08:31:27 +00:00
2023-05-12 05:59:32 +00:00
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();
2023-01-22 09:53:09 +00:00
}
2023-05-16 08:31:27 +00:00
if (!fs.existsSync(`${__dirname}/adminapi/www/adminapx/static/tpldata/setup_xx.json`)) {
// Need to generate a setup
2023-05-12 05:59:32 +00:00
console.log(
2023-05-16 08:31:27 +00:00
`\x1b[42m############################################################################################\x1b[0m\n\x1b[42mWellcome into apxtrib, you must run 'yarn setup nationId townId dns' to conf your town. \x1b[0m \n\x1b[42m where nationId have to exist (example: ants) townId is new and dns have to be a domaine set to listen on port 80 443 on this server (example wall-ants.ndda.fr redirect to 213.32.65.213 or usbfarm-ants redirect to 127.0.0.1). Check README's project to learn more.\x1b[0m\n\x1b[42m############################################################################################\x1b[0m`
2023-05-12 05:59:32 +00:00
);
process.exit();
2023-01-22 09:53:09 +00:00
}
2023-05-16 08:31:27 +00:00
const infotown = fs.readJsonSync(`${__dirname}/adminapi/www/adminapx/static/tpldata/setup_xx.json`)
if (!process.env.dirtown) process.env.dirtown=path.resolve(`${__dirname}/../${infotown.townId}-${infotown.nationId}`);
const conf = require(`${process.env.dirtown}/conf.json`);
2023-04-28 11:21:02 +00:00
// To make public this conf, careffull this localconf will be public, this the only difference between all apxtrib node
2023-05-16 08:31:27 +00:00
/*
2023-05-12 05:59:32 +00:00
const localconf = {
nationId: conf.nationId,
townId: conf.townId,
tribeId: conf.tribeId,
comment: "Generate by apxtrib.js with minimum of information",
};
fs.outputJsonSync(
2023-05-16 08:31:27 +00:00
`${__dirapi}nationchains/www/adminapx/static/tpldata/setup_en.json`,
2023-05-12 05:59:32 +00:00
localconf
2023-05-16 08:31:27 +00:00
);*/
2023-05-12 05:59:32 +00:00
// Run main express process
// Each tribe has a context (domain, plugins route, website ) are all describe into idx tribeId_all.json
// {"tribename":{"tribeId":"tribename","dns":[array of domain],"status":"unchain","nationId":"ants","townId":"usbfarm"}}
2023-01-22 09:53:09 +00:00
// dataclient .tribeids [] .DOMs [] .routes (plugins {url:name route:path}) .appname {tribeid:[website]}
2023-04-27 04:17:20 +00:00
//const dataclient = require( './api/models/Tribes' ).init();
2023-05-12 05:59:32 +00:00
const tribelist = fs.readJsonSync(
2023-05-16 08:31:27 +00:00
`${process.env.dirtown}/tribes/idx/tribeId_all.json`
2023-05-12 05:59:32 +00:00
);
let doms = conf.dns; // only dns of town during the init process
let tribeIds = [];
2023-05-16 08:31:27 +00:00
let routes = glob.sync(`${conf.dirapi}/api/routes/*.js`).map((f) => {
2023-05-12 05:59:32 +00:00
return { url: `/${path.basename(f, ".js")}`, route: f };
});
//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)
Object.keys(tribelist).forEach((t) => {
tribelist[t].dns.forEach((d) => {
const dm = d.split(".").slice(-2).join(".");
if (!doms.includes(dm)) doms.push(dm);
});
tribeIds.push(t);
});
console.log("Allowed DOMs to access to this apxtrib server: ", doms);
2023-04-13 05:46:35 +00:00
2023-04-27 04:17:20 +00:00
const app = express();
2023-05-12 05:59:32 +00:00
// load express parameter from conf
Object.keys(conf.api.appset).forEach((p) => {
app.set(p, conf.api.appset[p]);
});
2023-01-22 09:53:09 +00:00
// To set depending of data form or get size to send
2023-05-12 05:59:32 +00:00
app.use(bodyParser.urlencoded(conf.api.bodyparse.urlencoded));
2023-01-22 09:53:09 +00:00
// To set depending of post put json data size to send
2023-05-12 05:59:32 +00:00
app.use(express.json());
app.use(bodyParser.json(conf.api.bodyparse.json));
2023-04-27 04:17:20 +00:00
app.locals.tribeids = tribeIds;
2023-05-12 05:59:32 +00:00
console.log("app.locals.tribeids", app.locals.tribeids);
2023-01-22 09:53:09 +00:00
// Cors management
const corsOptions = {
2023-05-12 05:59:32 +00:00
origin: (origin, callback) => {
if (origin === undefined) {
callback(null, true);
} else if (origin.indexOf("chrome-extension") > -1) {
callback(null, true);
} else {
//console.log( 'origin', origin )
//marchais avant modif eslint const rematch = ( /^https?\:\/\/(.*)\:.*/g ).exec( origin )
const rematch = /^https?:\/\/(.*):.*/g.exec(origin);
//console.log( rematch )
let tmp = origin.replace(/http.?:\/\//g, "").split(".");
2023-01-22 09:53:09 +00:00
2023-05-12 05:59:32 +00:00
if (rematch && rematch.length > 1) tmp = rematch[1].split(".");
//console.log( 'tmp', tmp )
let dom = tmp[tmp.length - 1];
if (tmp.length > 1) {
dom = `${tmp[tmp.length - 2]}.${tmp[tmp.length - 1]}`;
}
console.log(
`origin: ${origin}, dom:${dom}, CORS allowed? : ${doms.includes(dom)}`
);
if (doms.includes(dom)) {
callback(null, true);
} else {
console.log(`Origin is not allowed by CORS`);
callback(new Error("Not allowed by CORS"));
}
}
},
exposedHeaders: Object.keys(conf.api.exposedHeaders),
2023-01-22 09:53:09 +00:00
};
// CORS
2023-05-12 05:59:32 +00:00
app.use(cors(corsOptions));
// Static Routes // try to use nginx route instead in comments
2023-04-28 11:21:02 +00:00
/*app.use( express.static( `${__dirname}/nationchains/tribes/${conf.mayorId}/www/cdn/public`, {
2023-01-22 09:53:09 +00:00
dotfiles: 'allow'
} ) );
2023-04-27 04:17:20 +00:00
*/
2023-01-22 09:53:09 +00:00
// Routers add any routes from /routes and /plugins
2023-05-12 05:59:32 +00:00
console.log("Routes available on this apxtrib instance");
console.log(routes);
routes.forEach((r) => {
try {
app.use(r.url, require(r.route));
} catch (err) {
console.log(
`\x1b[31m!!! WARNING issue with route ${r.route} from ${r.url} check err if route is key then solve err, if not just be aware that this route won't work on your server. If you are not the maintainer and no turn around please contact the email maintainer.\x1b[0m`
);
console.log("raise err-:", err);
}
});
2023-01-22 09:53:09 +00:00
2023-05-12 05:59:32 +00:00
app.listen(conf.api.port, () => {
2023-05-16 08:31:27 +00:00
let webaccess=`check in your browser that api works`;
conf.dns.forEach(u=>{webaccess+= `http://${u}:${conf.api.port}`;});
console.log(webaccess)
2023-05-12 05:59:32 +00:00
});
console.log(
"\x1b[42m\x1b[37m",
"Made with love for people's freedom, enjoy !!!",
"\x1b[0m"
);