1
0
forked from apxtri/apxtri
This commit is contained in:
philc 2024-02-16 08:39:42 +01:00
parent a95bfaf00f
commit c89b62befc
7 changed files with 173 additions and 128 deletions

View File

@ -1,7 +1,6 @@
const conf = require(`../../conf/townconf.json`); const conf = require(`../../conf/townconf.json`);
const l=require('../tools/log.js'); const currentmod='checkHeaders';
//l.showlog= true; // force log as well in prod and dev const log = conf.api.activelog.includes(currentmod)
l.context="apxtri";
/** /**
* @api {get} http://header/CheckHeaders - CheckHeaders * @api {get} http://header/CheckHeaders - CheckHeaders
* @apiGroup Middlewares * @apiGroup Middlewares
@ -55,9 +54,9 @@ const checkHeaders = (req, res, next) => {
if (!req.header("xlang") && req.header("Content-Language")) if (!req.header("xlang") && req.header("Content-Language"))
req.params.xlang = req.header("Content-Language"); req.params.xlang = req.header("Content-Language");
let missingheader = []; let missingheader = [];
//console.log("req.headers", req.headers); if (log) console.log(currentmod," req.headers", req.headers);
for (const h of conf.api.exposedHeaders) { for (const h of conf.api.exposedHeaders) {
//console.log( h, req.header( h ) ) if (log) console.log(currentmod, h, req.header( h ) )
if (req.params[h]) { if (req.params[h]) {
header[h] = req.params[h]; header[h] = req.params[h];
} else if (req.header(h)) { } else if (req.header(h)) {
@ -66,7 +65,7 @@ const checkHeaders = (req, res, next) => {
missingheader.push(h); missingheader.push(h);
} }
} }
// console.log( 'pass header', header ) if (log) console.log( currentmod, ' pass header', header )
// store in session the header information // store in session the header information
req.session.header = header; req.session.header = header;
// Each header have to be declared // Each header have to be declared
@ -96,8 +95,8 @@ const checkHeaders = (req, res, next) => {
} }
if (!conf.api.languages.includes(header.xlang)) { if (!conf.api.languages.includes(header.xlang)) {
const info="warning language requested does not exist force to english"; const info="warning language requested does not exist force to english";
l.og(info); if (log) console.log(currentmod, info);
l.ogprod(req.header("xtribe"),info); console.log(Date.now(),currentmod, req.header("xtribe"),info);
header.xlang = "en"; header.xlang = "en";
} }
//set anonymous profil //set anonymous profil

View File

@ -6,9 +6,9 @@ const glob = require("glob");
// const openpgp = require("/media/phil/usbfarm/apxtri/node_modules/openpgp/dist/node/openpgp.js"); // const openpgp = require("/media/phil/usbfarm/apxtri/node_modules/openpgp/dist/node/openpgp.js");
const openpgp = require("openpgp"); const openpgp = require("openpgp");
const l=require('../tools/log.js'); const conf = require(`../../conf/townconf.json`);
l.showlog= false; // force log as well in prod and dev const currentmod='isAuthenticated';
l.context="isAuthenticated"; const log = conf.api.activelog.includes(currentmod)
/** /**
* @api {get} http://header/istauthenticated - isAuthenticated * @api {get} http://header/istauthenticated - isAuthenticated
* @apiGroup Middlewares * @apiGroup Middlewares
@ -42,7 +42,7 @@ const isAuthenticated = async (req, res, next) => {
let menagedone = fs.existsSync( let menagedone = fs.existsSync(
`../tmp/tokens/menagedone${currentday}` `../tmp/tokens/menagedone${currentday}`
); );
l.og(`menagedone${currentday} was it done today?:${menagedone}`); if (menagedone) console.log(Date.now(),`menagedone${currentday} was it done today?:${menagedone}`);
if (!menagedone) { if (!menagedone) {
// clean oldest // clean oldest
const tsday = dayjs().valueOf(); // now in timestamp format const tsday = dayjs().valueOf(); // now in timestamp format
@ -67,7 +67,7 @@ const isAuthenticated = async (req, res, next) => {
); );
} }
//Check register in tmp/tokens/ //Check register in tmp/tokens/
l.og("isAuthenticate?", req.session.header, req.body); if (log) console.log( currentmod," isAuthenticate?", req.session.header, req.body);
const resnotauth = { const resnotauth = {
ref: "middlewares", ref: "middlewares",
@ -81,7 +81,7 @@ const isAuthenticated = async (req, res, next) => {
req.session.header.xalias == "anonymous" || req.session.header.xalias == "anonymous" ||
req.session.header.xhash == "anonymous" req.session.header.xhash == "anonymous"
) { ) {
l.og("alias anonymous means not auth"); if (log) console.log(currentmod,"alias anonymous means not auth");
resnotauth.status = 401; resnotauth.status = 401;
return res.status(resnotauth.status).json(resnotauth); return res.status(resnotauth.status).json(resnotauth);
} }
@ -100,9 +100,9 @@ const isAuthenticated = async (req, res, next) => {
const failstamp = `../tmp/tokens/${alias}.json`; const failstamp = `../tmp/tokens/${alias}.json`;
if (action == "clean") { if (action == "clean") {
//to reinit bruteforce checker //to reinit bruteforce checker
l.og("try to clean penalty file ", failstamp); if (log) console.log(currentmod, "try to clean penalty file ", failstamp);
fs.remove(failstamp, (err) => { fs.remove(failstamp, (err) => {
if (err) console.log("Check forcebrut ", err); if (err) console.log(Date.now(),currentmod,"Check forcebrut ", err);
}); });
} else if (action == "penalty") { } else if (action == "penalty") {
const stamp = fs.existsSync(failstamp) const stamp = fs.existsSync(failstamp)
@ -111,17 +111,14 @@ const isAuthenticated = async (req, res, next) => {
stamp.lastfail = dayjs().format(); stamp.lastfail = dayjs().format();
stamp.numberfail += 1; stamp.numberfail += 1;
fs.outputJSON(failstamp, stamp); fs.outputJSON(failstamp, stamp);
l.og("penalty:", stamp); if (log) console.log(currentmod,"penalty:", stamp);
await sleep(stamp.numberfail * 100); //increase of 0,1 second the answer time per fail await sleep(stamp.numberfail * 100); //increase of 0,1 second the answer time per fail
l.og("time out penalty"); if (log) console.log(currentmod,"time out penalty");
} }
}; };
if (!fs.existsSync(tmpfs)) { if (!fs.existsSync(tmpfs)) {
// need to check detached sign // need to check detached sign
let publickey = ""; let publickey = "";
l.og(process.cwd());
l.og(process.env.PWD);
l.og(__dirname);
const aliasinfo = `../nationchains/pagans/itm/${req.session.header.xalias}.json`; const aliasinfo = `../nationchains/pagans/itm/${req.session.header.xalias}.json`;
if (fs.existsSync(aliasinfo)) { if (fs.existsSync(aliasinfo)) {
publickey = fs.readJsonSync(aliasinfo).publickey; publickey = fs.readJsonSync(aliasinfo).publickey;
@ -130,26 +127,26 @@ const isAuthenticated = async (req, res, next) => {
publickey = req.body.publickey; publickey = req.body.publickey;
} }
if (publickey == "") { if (publickey == "") {
l.og("alias unknown"); if (log) console.log(currentmod,"header xalias unknown:",req.session.header.xalias);
resnotauth.status = 404; resnotauth.status = 404;
resnotauth.data.xaliasexists = false; resnotauth.data.xaliasexists = false;
return res.status(resnotauth.status).send(resnotauth); return res.status(resnotauth.status).send(resnotauth);
} }
l.og("publickey", publickey); if (log) console.log(currentmod,"publickey", publickey);
if (publickey.substring(0, 31) !== "-----BEGIN PGP PUBLIC KEY BLOCK") { if (publickey.substring(0, 31) !== "-----BEGIN PGP PUBLIC KEY BLOCK") {
l.og("Publickey is not valid as armored key:", publickey); console.log(Date.now(),currentmod,"Publickey is not valid as armored key:", publickey);
await bruteforcepenalty(req.session.header.xalias, "penalty"); await bruteforcepenalty(req.session.header.xalias, "penalty");
resnotauth.status = 404; resnotauth.status = 404;
return res.status(resnotauth.status).send(resnotauth); return res.status(resnotauth.status).send(resnotauth);
} }
const clearmsg = Buffer.from(req.session.header.xhash, "base64").toString(); const clearmsg = Buffer.from(req.session.header.xhash, "base64").toString();
if (clearmsg.substring(0, 10) !== "-----BEGIN") { if (clearmsg.substring(0, 10) !== "-----BEGIN") {
l.og("xhash conv is not valid as armored key:", clearmsg); if (log) console.log(currentmod,"xhash conv is not valid as armored key:", clearmsg);
await bruteforcepenalty(req.session.header.xalias, "penalty"); await bruteforcepenalty(req.session.header.xalias, "penalty");
resnotauth.status = 404; resnotauth.status = 404;
return res.status(resnotauth.status).send(resnotauth); return res.status(resnotauth.status).send(resnotauth);
} }
l.og("clearmsg", clearmsg); if (log) console.log(currentmod, "clearmsg", clearmsg);
let signedMessage="" let signedMessage=""
const pubkey = await openpgp.readKey({ armoredKey: publickey }); const pubkey = await openpgp.readKey({ armoredKey: publickey });
try{ try{
@ -163,8 +160,8 @@ const isAuthenticated = async (req, res, next) => {
message: signedMessage, message: signedMessage,
verificationKeys: pubkey, verificationKeys: pubkey,
}); });
l.og(verificationResult); if (log) console.log(currentmod,verificationResult);
l.og(verificationResult.signatures[0].keyID.toHex()); if (log) console.log(currentmod,verificationResult.signatures[0].keyID.toHex());
try { try {
await verificationResult.signatures[0].verified; await verificationResult.signatures[0].verified;
if ( if (
@ -172,8 +169,7 @@ const isAuthenticated = async (req, res, next) => {
`${req.session.header.xalias}_${req.session.header.xdays}` `${req.session.header.xalias}_${req.session.header.xdays}`
) { ) {
resnotauth.msg = "signaturefailled"; resnotauth.msg = "signaturefailled";
l.og( if (log) console.log(currentmod,`message recu:${verificationResult.data} , message attendu:${req.session.header.xalias}_${req.session.header.xdays}`
`message recu:${verificationResult.data} , message attendu:${req.session.header.xalias}_${req.session.header.xdays}`
); );
await bruteforcepenalty(req.session.header.xalias, "penalty"); await bruteforcepenalty(req.session.header.xalias, "penalty");
resnotauth.status = 401; resnotauth.status = 401;
@ -181,18 +177,18 @@ const isAuthenticated = async (req, res, next) => {
} }
} catch (e) { } catch (e) {
resnotauth.msg = "signaturefailled"; resnotauth.msg = "signaturefailled";
l.og("erreur", e); if (log) console.log(currentmod,"erreur", e);
await bruteforcepenalty(req.session.header.xalias, "penalty"); await bruteforcepenalty(req.session.header.xalias, "penalty");
resnotauth.status = 401; resnotauth.status = 401;
return res.status(resnotauth.status).send(resnotauth); return res.status(resnotauth.status).send(resnotauth);
} }
// authenticated then get person profils (person = pagan for a xtrib) // authenticated then get person profils (person = pagan for a xtrib)
const person = `${process.env.dirtown}/tribes/${req.session.header.xtribe}/objects/persons/itm/${req.session.header.xalias}.json`; const person = `../nationchains/tribes/${req.session.header.xtribe}/objects/persons/itm/${req.session.header.xalias}.json`;
l.og("Profils tribe/app management"); if (log) console.log(currentmod,"Profils tribe/app management");
l.og("person", person); if (log) console.log(currentmod,"person", person);
if (fs.existsSync(person)) { if (fs.existsSync(person)) {
const infoperson = fs.readJSONSync(person); const infoperson = fs.readJSONSync(person);
l.og(infoperson); if (log) console.log(currentmod,"infoperson",infoperson);
infoperson.profils.forEach((p) => { infoperson.profils.forEach((p) => {
if (!req.session.header.xprofils.includes(p)) req.session.header.xprofils.push(p); if (!req.session.header.xprofils.includes(p)) req.session.header.xprofils.push(p);
}) })
@ -205,7 +201,7 @@ const isAuthenticated = async (req, res, next) => {
req.session.header.xprofils = fs.readJSONSync(tmpfs); req.session.header.xprofils = fs.readJSONSync(tmpfs);
} }
bruteforcepenalty(req.session.header.xalias, "clean"); bruteforcepenalty(req.session.header.xalias, "clean");
l.og(`${req.session.header.xalias} Authenticated`); if (log) console.log(currentmod,`${req.session.header.xalias} Authenticated`);
next(); next();
}; };
module.exports = isAuthenticated; module.exports = isAuthenticated;

View File

@ -6,7 +6,8 @@ const axios = require("axios");
const conf = require(`../../conf/townconf.json`); const conf = require(`../../conf/townconf.json`);
const Checkjson = require(`./Checkjson.js`); const Checkjson = require(`./Checkjson.js`);
const { promiseHooks } = require("v8"); const { promiseHooks } = require("v8");
const currentmod = "Odmdb";
const log = conf.api.activelog.includes(currentmod);
/** /**
* This manage Objects for indexing, searching, checking and act to CRUD * This manage Objects for indexing, searching, checking and act to CRUD
* @objectPathName = objectpath/objectname * @objectPathName = objectpath/objectname
@ -25,7 +26,7 @@ const { promiseHooks } = require("v8");
* } * }
* *
* Specifics key in schema to apxtri: * Specifics key in schema to apxtri:
* apxid : the field value to use to store item * apxid : the field value to use to store item apx
* apxuniquekey : list of field that has to be unique you cannot have 2 itm with same key value * apxuniquekey : list of field that has to be unique you cannot have 2 itm with same key value
* apxidx : list of index file /idx/ * apxidx : list of index file /idx/
* { "name":"lst_fieldA", "keyval": "alias" }, => lst_fieldA.json = [fieldAvalue1,...] * { "name":"lst_fieldA", "keyval": "alias" }, => lst_fieldA.json = [fieldAvalue1,...]
@ -47,7 +48,8 @@ const { promiseHooks } = require("v8");
const Odmdb = {}; const Odmdb = {};
/** /**
* @api syncObject *const Checkjson = require(`../../../../../apxtri/models/Checkjson`);
@api syncObject
* @param {string} url to an existing object conf (/objectname/conf.json) * @param {string} url to an existing object conf (/objectname/conf.json)
* @param {timestamp} timestamp * @param {timestamp} timestamp
* 0 => rebuild local object from all_{idapx}.json * 0 => rebuild local object from all_{idapx}.json
@ -150,40 +152,71 @@ Odmdb.updateObject = (objectPathname, meta) => {};
* *
* todo only local schema => plan a sync each 10minutes * todo only local schema => plan a sync each 10minutes
* @schemaPath local path adminapi/schema/objectName.json or /tribename/schema/objectName * @schemaPath local path adminapi/schema/objectName.json or /tribename/schema/objectName
* @validschema boolean if necessary to check schema or not mainly use when change schema * @validschema boolean if necessary to check schema or not mainly use when change schema;
* @lg language you want to get schema
* @return {status:200,data:{conf:"schemaconf",schema:"schemacontent"} } * @return {status:200,data:{conf:"schemaconf",schema:"schemacontent"} }
*/ */
Odmdb.Schema = (objectPathname, validschema) => { Odmdb.Schema = (objectPathname, validschema, lg="en") => {
const getpath = (schemaPath) => {
const replacelg = (data)=>{
// data.en version schema de base, data.fr version schema traduite
Object.keys(data.lg).forEach(k=>{
console.log(k)
if (data.lg[k].title) data.en[k].title = data.lg[k].title
if (data.lg[k].description) data.en[k].description = data.lg[k].description
if (data.lg.properties){
console.log('properties')
console.log(data.en.properties)
console.log(data.lg.properties)
const res = replacelg({en:data.en.properties,lg:data.lg.properties})
data.lg.properties=res.lg
data.en.properties=res.en
}
})
return data
}
const getschemalg = (schemaPath,lg) => {
if (schemaPath.slice(-5) != ".json") schemaPath += ".json"; if (schemaPath.slice(-5) != ".json") schemaPath += ".json";
if (schemaPath.substring(0, 4) == "http") { if (schemaPath.substring(0, 4) == "http") {
// lance requete http pour recuperer le schema avec un await axios // lance requete http pour recuperer le schema avec un await axios
} else { } else {
schemaPath = `../nationchains/tribes/${schemaPath}`; schemaPath = `../nationchains/tribes/${schemaPath}`;
/*if (schemaPath.substring(0, 9) == "adminapi/") { console.log(path.resolve(schemaPath))
schemaPath = `${conf.dirapi}/${schemaPath}`;
} else {
schemaPath = `${conf.dirtown}/tribes/${schemaPath}`;
}*/
if (!fs.existsSync(schemaPath)) { if (!fs.existsSync(schemaPath)) {
return {}; return {};
} else { } else {
return fs.readJsonSync(schemaPath); let schemalg = fs.readJsonSync(schemaPath);
if (lg!="en"){
let lgtrans={}
try{
lgtrans=fs.readJsonSync(schemaPath.replace('/schema/','/schema/lg/').replace('.json',`_${lg}.json`));
const res= replacelg({en:schemalg,lg:lgtrans})
//console.log(res.en.title,res.lg.title)
schemalg=res.en
}catch(err){
// console.log('Err',err)
// no translation file deliver en by default
}
}
return schemalg
} }
} }
}; };
console.log(`${objectPathname}/conf.json`); if (log) console.log(currentmod,`${objectPathname}/conf.json`);
const confschema = fs.readJsonSync(`${objectPathname}/conf.json`);
console.log(confschema);
const res = { const res = {
status: 200, status: 200,
ref: "Odmdb", ref: "Odmdb",
msg: "getschema", msg: "getschema",
data: { conf: confschema }, data: {},
}; };
res.data.schema = getpath(confschema.schema);
if (Object.keys(res.data.schema).length == 0) { if (fs.existsSync(`${objectPathname}/conf.json`)) {
res.data.conf=fs.readJsonSync(`${objectPathname}/conf.json`);
res.data.schema = getschemalg(res.data.conf.schema,lg)
}else{
res.data.conf={}
}
if (!res.data.schema || Object.keys(res.data.schema).length == 0 ) {
return { return {
status: 404, status: 404,
ref: "Odmdb", ref: "Odmdb",
@ -192,9 +225,9 @@ Odmdb.Schema = (objectPathname, validschema) => {
}; };
} }
//looking for type:object with $ref to load and replace by ref content (ref must be adminapi/ or tribeid/)
//@todo only 1 level $ref if multi level need to rewrite with recursive call //@todo only 1 level $ref if multi level need to rewrite with recursive call
Object.keys(res.data.schema.properties).forEach((p) => { Object.keys(res.data.schema.properties).forEach((p) => {
//looking for type:object with $ref to load and replace by ref content (ref must be adminapi/ or tribeid/)
if ( if (
res.data.schema.properties[p].type == "object" && res.data.schema.properties[p].type == "object" &&
res.data.schema.properties[p]["$ref"] res.data.schema.properties[p]["$ref"]
@ -210,6 +243,25 @@ Odmdb.Schema = (objectPathname, validschema) => {
res.data.schema.properties[p] = subschema; res.data.schema.properties[p] = subschema;
} }
} }
//looking for options:{"$ref":"../objects/options/xxx.json"}
//to add enum:[] = content of options available
if (
res.data.schema.properties[p].options &&
res.data.schema.properties[p].options["$ref"]
) {
const optionsfile = path.resolve(`${objectPathname}/${res.data.schema.properties[p].options["$ref"]}`)
if (!fs.existsSync(optionsfile)){
res.status = 404;
res.msg = "missingref";
res.data.missingref = res.data.schema.properties[p]["$ref"];
return res;
}else{
if (!res.data.schema.apxref) {res.data.schema.apxref=[]}
if (!res.data.schema.apxref.includes(res.data.schema.properties[p].options["$ref"]))
res.data.schema.apxref.push(res.data.schema.properties[p].options["$ref"])
res.data.schema.properties[p].enum=fs.readJSONSync(optionsfile)
}
}
}); });
if (!res.data.schema.apxid) { if (!res.data.schema.apxid) {
@ -300,7 +352,7 @@ Odmdb.r = (objectPathname, apxid, role) => {
status: 403, status: 403,
ref: "Odmdb", ref: "Odmdb",
msg: "profilnotallow", msg: "profilnotallow",
data: { person: apxid, }, data: { person: apxid },
}; };
} }
const data = {}; const data = {};
@ -384,8 +436,8 @@ Odmdb.ASUPreads = (objectPathname, apxidlist, role, propertiesfilter) => {
* example: {"C":[],"R":[properties list],"U":[properties ist],"D":[]} * example: {"C":[],"R":[properties list],"U":[properties ist],"D":[]}
*/ */
Odmdb.accessright = (apxaccessrights, role) => { Odmdb.accessright = (apxaccessrights, role) => {
//console.log("apxaccessrights",apxaccessrights) //if (log) console.log(currentmod,"apxaccessrights",apxaccessrights)
//console.log("role",role) //if (log) console.log(currentmod,"role",role)
const accessright = {}; const accessright = {};
role.xprofils.forEach((p) => { role.xprofils.forEach((p) => {
if (apxaccessrights[p]) { if (apxaccessrights[p]) {
@ -397,7 +449,7 @@ Odmdb.accessright = (apxaccessrights, role) => {
...new Set([...accessright[act], ...apxaccessrights[p][act]]), ...new Set([...accessright[act], ...apxaccessrights[p][act]]),
]; ];
} }
//console.log(act,accessright[act]) //if (log) console.log(currentmod,act,accessright[act])
}); });
} }
}); });
@ -483,7 +535,7 @@ Odmdb.cud = (objectPathname, crud, itm, role, runindex = true) => {
getschema.data.schema.apxaccessrights, getschema.data.schema.apxaccessrights,
role role
); );
console.log("accessright", accessright); if (log) console.log(currentmod,"accessright", accessright);
if ( if (
(crud == "C" && !accessright.C) || (crud == "C" && !accessright.C) ||
(crud == "D" && !accessright.D) || (crud == "D" && !accessright.D) ||
@ -526,17 +578,17 @@ Odmdb.cud = (objectPathname, crud, itm, role, runindex = true) => {
if (chkdata.status != 200) return chkdata; if (chkdata.status != 200) return chkdata;
if (!getschema.data.schema.apxuniquekey) if (!getschema.data.schema.apxuniquekey)
getschema.data.schema.apxuniquekey = []; getschema.data.schema.apxuniquekey = [];
console.log(`${objectPathname}/itm/${chkdata.data.apxid}.json`); if (log) console.log(currentmod,`${objectPathname}/itm/${chkdata.data.apxid}.json`);
console.log(chkdata.data.itm); if (log) console.log(currentmod,chkdata.data.itm);
fs.outputJSONSync( fs.outputJSONSync(
`${objectPathname}/itm/${chkdata.data.apxid}.json`, `${objectPathname}/itm/${chkdata.data.apxid}.json`,
chkdata.data.itm chkdata.data.itm
); );
} }
//console.log("getschema", getschema); //if (log) console.log(currentmod,"getschema", getschema);
//rebuild index if requested //rebuild index if requested
console.log("runidx", runindex); if (log) console.log(currentmod,"runidx", runindex);
console.log(objectPathname); if (log) console.log(currentmod,objectPathname);
if (runindex) Odmdb.runidx(objectPathname, getschema.data.schema); if (runindex) Odmdb.runidx(objectPathname, getschema.data.schema);
getschema.data.conf.lastupdatedata = dayjs().toISOString(); getschema.data.conf.lastupdatedata = dayjs().toISOString();
fs.outputJSONSync(`${objectPathname}/conf.json`, getschema.data.conf); fs.outputJSONSync(`${objectPathname}/conf.json`, getschema.data.conf);
@ -559,7 +611,7 @@ Odmdb.cud = (objectPathname, crud, itm, role, runindex = true) => {
* *
*/ */
Odmdb.runidx = (objectPathname, schema) => { Odmdb.runidx = (objectPathname, schema) => {
console.log(`idx for ${objectPathname}`); if (log) console.log(currentmod,`idx for ${objectPathname}`);
if (!schema || !schema.apxid) { if (!schema || !schema.apxid) {
const getschema = Odmdb.Schema(objectPathname, true); const getschema = Odmdb.Schema(objectPathname, true);
if (getschema.status != 200) return getschema; if (getschema.status != 200) return getschema;
@ -634,13 +686,18 @@ Odmdb.runidx = (objectPathname, schema) => {
ventil[n].data[val].push(itm[schema.apxid]); ventil[n].data[val].push(itm[schema.apxid]);
}); });
} }
if (keep && ventil[n].type == "distribution" && ventil[n].isobject && itm[ventil[n].keyval.split('.')[0]]) { if (
keep &&
ventil[n].type == "distribution" &&
ventil[n].isobject &&
itm[ventil[n].keyval.split(".")[0]]
) {
let itmval = JSON.parse(JSON.stringify(itm)); let itmval = JSON.parse(JSON.stringify(itm));
console.log( ventil[n].keyval) if (log) console.log(currentmod,ventil[n].keyval);
console.log(itmval) if (log) console.log(currentmod,itmval);
ventil[n].keyval ventil[n].keyval
.split(".") .split(".")
.forEach((i) => itmval = itmval[i] ? itmval[i] : null); .forEach((i) => (itmval = itmval[i] ? itmval[i] : null));
if (itmval) { if (itmval) {
if (!ventil[n].data[itmval]) ventil[n].data[itmval] = []; if (!ventil[n].data[itmval]) ventil[n].data[itmval] = [];
ventil[n].data[itmval].push(itm[schema.apxid]); ventil[n].data[itmval].push(itm[schema.apxid]);
@ -649,7 +706,7 @@ Odmdb.runidx = (objectPathname, schema) => {
}); });
}); });
Object.keys(ventil).forEach((n) => { Object.keys(ventil).forEach((n) => {
//console.log(`${objectPathname}/idx/${ventil[n].name}.json`) //if (log) console.log(currentmod,`${objectPathname}/idx/${ventil[n].name}.json`)
fs.outputJSON( fs.outputJSON(
`${objectPathname}/idx/${ventil[n].name}.json`, `${objectPathname}/idx/${ventil[n].name}.json`,
ventil[n].data ventil[n].data
@ -687,15 +744,15 @@ Odmdb.ASUPidxfromitm = (
idxs = [], idxs = [],
schema schema
) => { ) => {
console.log(`idxfromitem for ${objectPathname} action:${crud}`); if (log) console.log(currentmod,`idxfromitem for ${objectPathname} action:${crud}`);
if (!schema || !schema.apxid) { if (!schema || !schema.apxid) {
const getschema = Odmdb.Schema(objectPathname, true); const getschema = Odmdb.Schema(objectPathname, true);
if (getschema.status != 200) return getschema; if (getschema.status != 200) return getschema;
schema = getschema.data.schema; schema = getschema.data.schema;
} }
console.log(schema.apxuniquekey); if (log) console.log(currentmod,schema.apxuniquekey);
const itms = crud == "I" ? glob.sync(`${objectPathname}/itm/*.json`) : [itm]; const itms = crud == "I" ? glob.sync(`${objectPathname}/itm/*.json`) : [itm];
console.log(itms); if (log) console.log(currentmod,itms);
if (crud == "I") { if (crud == "I") {
//reinit all idx //reinit all idx
idxs.forEach((idx) => { idxs.forEach((idx) => {
@ -708,7 +765,7 @@ Odmdb.ASUPidxfromitm = (
if (crud == "I") { if (crud == "I") {
itm = fs.readJSONSync(i); itm = fs.readJSONSync(i);
} }
//console.log(itm); //if (log) console.log(currentmod,itm);
idxs.forEach((idx) => { idxs.forEach((idx) => {
const keyvalisunique = schema.apxuniquekey.includes(idx.keyval); // check if keyval is unique mean store as an object (or string) else store as an array const keyvalisunique = schema.apxuniquekey.includes(idx.keyval); // check if keyval is unique mean store as an object (or string) else store as an array
const idxsrc = `${objectPathname}/idx/${idx.name}.json`; const idxsrc = `${objectPathname}/idx/${idx.name}.json`;
@ -722,8 +779,8 @@ Odmdb.ASUPidxfromitm = (
idxtoreindex.push(idx); //@todo idxtoreindex.push(idx); //@todo
} }
} }
console.log(idx.keyval); if (log) console.log(currentmod,idx.keyval);
console.log(itm[idx.keyval]); if (log) console.log(currentmod,itm[idx.keyval]);
if ( if (
["C", "U", "I"].includes(crud) && ["C", "U", "I"].includes(crud) &&

View File

@ -5,5 +5,7 @@
"errsendmail":"Une erreur s'est produite lors de l'envoie de l'email", "errsendmail":"Une erreur s'est produite lors de l'envoie de l'email",
"successfullsentemail":"Email correctement envoyé", "successfullsentemail":"Email correctement envoyé",
"errsendsms":"Une erreur s'est produite lors de l'envoie du sms", "errsendsms":"Une erreur s'est produite lors de l'envoie du sms",
"successfullsentsms":"Sms bien envoyé à {{To}}" "successfullsentsms":"Sms bien envoyé à {{To}}",
"registersuccess":"Vous avez bien été enregistré pour être recontacté.",
"formaterror":"Verifier vos données"
} }

View File

@ -12,7 +12,7 @@
}, },
"scripts": { "scripts": {
"startapx": "pm2 start apxtri.js --log-date-format 'DD-MM HH:mm:ss.SSS'", "startapx": "pm2 start apxtri.js --log-date-format 'DD-MM HH:mm:ss.SSS'",
"restartapx": "pm2 restart --log-date-format 'DD-MM HH:mm:ss.SSS'", "restartapx": "pm2 restart apxtri.js --log-date-format 'DD-MM HH:mm:ss.SSS'",
"dev": "NODE_MODE=dev node apxtri.js", "dev": "NODE_MODE=dev node apxtri.js",
"unittest": "node unittest.js", "unittest": "node unittest.js",
"apidoc": "apidoc -c ../conf/apidoc/apidoc_$tribe.json -o ../nationchains/tribes/$tribe/www/cdn/apidoc/", "apidoc": "apidoc -c ../conf/apidoc/apidoc_$tribe.json -o ../nationchains/tribes/$tribe/www/cdn/apidoc/",

View File

@ -15,58 +15,50 @@ const router = express.Router();
* @apiGroup Trackings * @apiGroup Trackings
* @apiName trackingsystem * @apiName trackingsystem
* @apiDescription * @apiDescription
*
* **WARNING** a cors issue must be fix, currently this tracking work for the same domain.
*
* without header:<br> * without header:<br>
* <code>https://dns.xx/trk/pathtofile?alias=anonymous&uuid=1b506f71-1bff-416c-9057-cb8b86296f60&src=btnregister&version=1&lg=fr </code> * <code>https://dns.xx/trk/pathtofile?alias=anonymous&uuid=1b506f71-1bff-416c-9057-cb8b86296f60&srckey=btnregister&version=1&lg=fr </code>
* *
* with header<br> * with header<br>
* <code>https://dns.xx/trk/pathtofile?srckey=btnregister&version=1</code> * <code>https://dns.xx/trk/pathtofile?srckey=btnregister&version=1</code>
* *
* where pathtofile is a ressource accessible from https://dns.xx/pathtofile * where pathtofile is a ressource accessible from https://dns.xx/pathtofile
* For dummy pathtofile for apxtri project, you have:<br>
* /cdn/log/1x1.png (a 1pixel image 95 bytes )
* /cdn/log/empty.json (an empty jason 2 bytes)
*
* html usage to track a loading page or email when a picture is load * html usage to track a loading page or email when a picture is load
* using apxwebapp in /src/ we got: * using apxwebapp in /src/ we got:
* <code> < img src="static/img/photo.jpg" data-trksrckey="loadpage" data-version="1" > </code> * <code> < img src="static/img/photo.jpg" data-trksrckey="loadpage" data-version="1" > </code>
* *
* using html + apx.js (or at least with header {xalias,xuuid,xlang})
* <code>< img lazysrc="trk/static/img/photo.jpg data-trksrckey="loadpage" data-version="1" ></code>
*
* in js action: * in js action:
* *
* <code> * <code> <a data-trksrckey="linktoblabla" href='https:..' onclick="apx.trackvisit("btnaction",1);actionfct();"></a></code>
* <button></button>
* <a data-trksrckey="linktoblabla" href='https:..'
* onclick="apx.trackvisit("btnaction",1);actionfct();">
* </a>
* </code>
* #will hit an eventlistener<br>
* <code> axios.get("https://dns.xx/trk/cdn/empty.json?alias=anonymous&uuid=1b506f71-1bff-416c-9057-cb8b86296f60&srckey=btnregister&version=1");
* </code>
* *
* #or if no js available (example:email or pdf document)<br> * To hit an eventlistener<br>
* <code> axios.get("https://dns.xx/trk/cdn/empty.json?alias=anonymous&uuid=1b506f71-1bff-416c-9057-cb8b86296f60&srckey=btnregister&version=1");</code>
*
* If no js available (example:email or pdf document)<br>
* <code> < img src="https://dns.xx/trk/static/img/photo.jpg?alias=anonymous&uuid=1b506f71-1bff-416c-9057-cb8b86296f60&srckey=loadpage&version=1"</code> * <code> < img src="https://dns.xx/trk/static/img/photo.jpg?alias=anonymous&uuid=1b506f71-1bff-416c-9057-cb8b86296f60&srckey=loadpage&version=1"</code>
* *
* <code> * <code><a href="https://dns.xx/trk/redirect?alias=anonymous&uuid=1b506f71-1bff-416c-9057-cb8b86296f60&srckey=loadpage&version=1&url=http://..." </code>
* <a href="https://dns.xx/trk/redirect?alias=anonymous&uuid=1b506f71-1bff-416c-9057-cb8b86296f60&srckey=loadpage&version=1&url=http://..."
* </code>
*
* will hit a tracker then redirect to url></a> *
*
* *
* This will hit a tracker then redirect to url></a> *
* *
* **if you use apx.js** : in html add in < button >, < img >, < a > tag data-trksrc="srckey" * **if you use apx.js** : in html add in < button >, < img >, < a > tag data-trksrc="srckey"
* <code> * <code>
* < img src="https://dns.xx/static/img/photo.jpg" data-trkversion="1" data-trksrckey="registerform"> * < img src="https://dns.xx/static/img/photo.jpg" data-trkversion="1" data-trksrckey="registerform">
* < button data-trksrc="https://dns.xx/static/img/photo.jpg" data-trkversion="1" data-trksrckey="registerform"> * < button data-trksrc="https://dns.xx/static/img/photo.jpg" data-trkversion="1" data-trksrckey="registerform">
* </code> * </code>
* A lazyloader can also be track.
* <code>< img lazysrc="trk/static/img/photo.jpg data-trksrckey="loadpage" data-version="1" ></code>
* *
* Tracking log are store into tribe/logs/nginx/tribe_appname.trk.log * Tracking log are store into tribe/logs/nginx/tribe_appname.trk.log<br>
* Src have to be manage in tribe/api/models/lg/src_en.json * Src have to be manage in tribe/api/models/lg/src_en.json<br>
* <code>{"srckey":{ * <code>{"srckey":{"app":"presentation|app|apptest","title":"","description":""}}</code>
* "app":"presentation|app|apptest",
* "title":"",
* "description":""
* }
* }
* </code>
* *
* @apiParam {String} alias=anonymous if authenticated we get from headers * @apiParam {String} alias=anonymous if authenticated we get from headers
* @apiParam {String} uuid a uuid v4 generate the first time a web page is open on a browser * @apiParam {String} uuid a uuid v4 generate the first time a web page is open on a browser

View File

@ -1,27 +1,26 @@
const fs = require("fs-extra"); const fs = require("fs-extra");
const dayjs = require("dayjs"); const dayjs = require("dayjs");
const conf = require(`../../conf/townconf.json`);
const l = {}; const l = {};
l.context=""; l.context="";
l.showlog=(process.env.NODE_MODE=="dev");
l.og = (...infos) => { l.og = (...infos) => {
// by default if NODE_MODE is dev => l.showlog at true // in apxtowns/towns/conf/townconf.json .api.activelog a list of context to log
// if l.showlog is set to false then it does not output log
// l.context is a prefixe to help understanding
// usage: // usage:
// const l=require('./tools/log.js'); // const l=require('./tools/log.js');
// l.showlog= true; // force log as well in prod and dev // l.context="apxtri"; // name of model route to find it easily
// l.context="apxtri"; // then l.og(str1,str2,array1,objet,...)
// l.og(stringify) //console.log(infos)
if (conf.api.activelog.includes(l.context)) {
if (l.showlog) { console.log(l.context,'-', ...infos);
console.log(l.context,'-', infos);
} }
//console.assert(conf.api.activelog.includes(l.context),infos)
}; };
l.ogprod = (tribe,info) => { l.ogprod = (tribe,info) => {
//store log in file /nationchains/tribes/{tribe}/logs/apxtri/apxtri_{tribe}.log
const logf = `../../nationchains/tribes/${tribe}/logs/apxtri/apxtri_${tribe}.log`; const logf = `../../nationchains/tribes/${tribe}/logs/apxtri/apxtri_${tribe}.log`;
const msg = `${days.js().toISOString()}###${tribe}###${info}`; const msg = `${days.js().toISOString()}###${l.context}###${tribe}###${info}`;
fs.appendFileSync(logf, msg); fs.appendFileSync(logf, msg);
console.log(msg) console.log(msg)
}; };