2023-12-07 12:04:19 +01:00
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 https : //gitea.ndda.fr/apxtri/apxtri/wiki/Devrules
To have a quick understanding and convention before doing deeply in source code
To share configuration :
process . env . dirtown is folder where town folder name / townId - nationId is accessible
2024-03-20 11:24:03 +01:00
const conf = require ( ` ../../../conf.json ` ) ;
2023-12-07 12:04:19 +01: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
* /
/ * *
* 1 st install for dev
* run $ node apxtri . js nationId : ants townId : devfarm dns : devfarm - ants
* then just yarn dev
* it create a folder outside . . / townId - nationId /
* To convert a dev into a chain town run again with relevant param :
* run $ node apxtri . js nationId : ants townId : devfarm dns : devfarm - ants
* check the web interface http : //dns
* then just yarn startpm2 your town is under PM2 control
*
*
* @ 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 ...
* /
// check nginx exist
if ( ! fs . existsSync ( "/etc/nginx/nginx.conf" ) ) {
2024-02-19 17:55:06 +01:00
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."
) ;
2023-12-07 12:04:19 +01:00
process . exit ( ) ;
}
const param = { } ;
argv . slice ( 2 ) . forEach ( ( arg ) => {
const kv = arg . split ( ":" ) ;
if ( kv . length == 2 ) {
param [ kv [ 0 ] ] = kv [ 1 ] ;
}
} ) ;
2024-03-20 11:24:03 +01:00
if ( ! fs . existsSync ( "../../conf.json" ) ) {
2023-12-07 12:04:19 +01:00
// This is a first install
2024-02-19 17:55:06 +01:00
const nam = path . resolve ( ".." ) . split ( "/" ) . slice ( - 1 ) [ 0 ] . split ( "-" ) ;
const town = nam [ 0 ] ;
const nation = nam [ 1 ] ;
2023-12-07 12:04:19 +01:00
// doit exister param.dns pour mettre à jour le conf.json pour la conf adminapi
//run setup process
}
// 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 ( ) ;
}
}
* /
2024-03-20 11:24:03 +01:00
const conf = require ( path . resolve ( ` ../../conf.json ` ) ) ;
2024-03-15 08:49:23 +01:00
let doms = conf . dns ; // only dns of town during the init process
2024-02-19 17:55:06 +01:00
const currentmod = "apxtri" ;
const log = conf . api . activelog . includes ( currentmod ) ;
2024-02-16 07:55:29 +01:00
2024-02-19 17:55:06 +01:00
// Create and update ./nationchains plutot que cette fonction
2023-12-07 12:04:19 +01:00
// A creuser et voir comment synchro
/ * c o n s t { u p d a t e o b j e c t s f r o m f r e s h e s t t o w n } = r e q u i r e ( " . / m o d e l s / N a t i o n s . j s " ) ;
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 = { } ;
2024-03-15 08:49:23 +01:00
if ( fs . existsSync ( ` ../../idx/tribeId_all.json ` ) ) {
tribelist = fs . readJsonSync ( ` ../../idx/tribeId_all.json ` ) ;
2023-12-07 12:04:19 +01:00
}
2024-03-15 08:49:23 +01:00
let tribeIds = Object . keys ( tribelist ) ;
// context is store in tribes/itm/tribename.json ={contexte:{routes:[],models:[{model:,tplstringslg:[]}]}
2023-12-07 12:04:19 +01:00
//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)
2024-03-15 08:49:23 +01:00
let routes = [ ]
tribeIds . forEach ( ( t ) => {
2023-12-07 12:04:19 +01:00
tribelist [ t ] . dns . forEach ( ( d ) => {
const dm = d . split ( "." ) . slice ( - 2 ) . join ( "." ) ;
if ( ! doms . includes ( dm ) ) doms . push ( dm ) ;
} ) ;
2024-03-15 08:49:23 +01:00
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 ) ;
2023-12-07 12:04:19 +01:00
} ) ;
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 ) ) ;
2024-02-19 17:55:06 +01:00
app . disable ( "x-powered-by" ) ; // for security
2023-12-07 12:04:19 +01:00
app . locals . tribeids = tribeIds ;
2024-03-15 08:49:23 +01:00
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
2024-02-27 12:36:31 +01:00
let originlst = "test" ;
2024-02-19 17:55:06 +01:00
doms . forEach ( ( d ) => {
2024-02-27 12:36:31 +01:00
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:" ,
2024-02-27 12:37:56 +01:00
cor , "headers allowed: [" , conf . api . exposedHeaders . join ( ',' ) , "] match with reg:" , regtxt
2024-02-27 12:36:31 +01:00
) ;
cors ( {
origin : cor ,
allowedHeaders : conf . api . exposedHeaders ,
exposedHeaders : conf . api . exposedHeaders ,
credentials : true ,
preflightContinue : false ,
optionsSuccessStatus : 204
} ) ;
next ( ) ;
2024-02-19 17:55:06 +01:00
} ) ;
2024-02-16 07:55:29 +01:00
2023-12-07 12:04:19 +01:00
// Routers add any routes from /routes and /plugins
2024-02-16 07:55:29 +01:00
let logroute = "Routes available on this apxtri instance: \n" ;
2023-12-07 12:04:19 +01:00
routes . forEach ( ( r ) => {
try {
2024-02-19 17:55:06 +01:00
logroute += r . url . padEnd ( 30 , " " ) + r . route + "\n" ;
2023-12-07 12:04:19 +01:00
app . use ( r . url , require ( r . route ) ) ;
} catch ( err ) {
logroute += " (err check it module.exports=router;? or ...)\n======\n " ;
2024-02-16 07:55:29 +01:00
console . log ( "raise err-:" , err ) ;
2023-12-07 12:04:19 +01:00
}
} ) ;
2024-02-19 17:55:06 +01:00
if ( log ) {
console . log ( currentmod , logroute ) ;
if ( process . env . NODE _MODE == "dev" )
console . log (
` \x 1b[42m############################################################################################ \x 1b[0m \n \x 1b[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 \x 1b[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. \x 1b[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 \x 1b[42m############################################################################################ \x 1b[0m `
) ;
2023-12-07 12:04:19 +01:00
}
2023-12-29 13:38:47 +01:00
2023-12-07 12:04:19 +01:00
app . listen ( conf . api . port , ( ) => {
2024-02-27 12:36:31 +01:00
let webaccess = ` api waits request on port: ${ conf . api . port } for ` ;
2023-12-07 12:04:19 +01:00
conf . dns . forEach ( ( u ) => {
2024-02-27 12:36:31 +01:00
webaccess += ` ${ u } /api/ ` ;
2023-12-07 12:04:19 +01:00
} ) ;
2024-02-19 17:55:06 +01:00
if ( log ) console . log ( currentmod , webaccess ) ;
2023-12-07 12:04:19 +01:00
} ) ;
console . log (
"\x1b[42m\x1b[37m" ,
"Made with love for people's freedom, enjoy !!!" ,
"\x1b[0m"
) ;