diff --git a/README.md b/README.md index 166a0db..32cb172 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## apxtri  Decentralized Autonomous Organisation (DAO) for Libertarian +## apxtri  Decentralized Autonomous Organisation (DAO) You are here on the tech side, to understand under the wood how it works and how you can contribute to this tech journey. See [apxtri web site](https://apxtri.crabdance.com) how to create a new social world with apxtri. @@ -35,7 +35,7 @@ All actors will have the same target to respect contracts and are free to leave /idx/ list of indexName.json /itm/ list of object content store by apxid.json (unique key to identify an ite in a collection of items object /conf.json Version list and schema link that define this object - + some key objects /pagans/ Unique numeric ID shared accross all node (towns) /towns/ Unique town name shared accross all node by domain name + IP diff --git a/models/Odmdb.js b/models/Odmdb.js index 97bdf7d..c3a39e4 100644 --- a/models/Odmdb.js +++ b/models/Odmdb.js @@ -214,42 +214,41 @@ Odmdb.Schema = (objectPathname, validschema, lg = "en") => { } } }; - const convoptionstoenum=(propertie,lg)=>{ + const convoptionstoenum = (propertie, lg) => { if (!propertie.options) return propertie; - if (!(propertie.options["$ref"])){ - propertie.msg="missingref" - return propertie + if (!propertie.options["$ref"]) { + propertie.msg = "missingref"; + return propertie; } let optionsfile; - let optionstype; - if (propertie.options["$ref"].includes("/options/")) { - optionstype = "options"; - optionsfile = path.resolve( - `../../${propertie.options["$ref"]}_${lg}.json` - ); + let optionstype; + if (propertie.options["$ref"].includes("/options/")) { + propertie.comment = `options:${propertie.options["$ref"]}}`; + optionstype = "options"; + optionsfile = path.resolve( + `../../${propertie.options["$ref"]}_${lg}.json` + ); + } + if (propertie.options["$ref"].includes("/idx/")) { + (propertie.comment = `itms:${propertie.options["$ref"]}}`), + (optionstype = "idx"); + optionsfile = path.resolve(`../../${propertie.options["$ref"]}.json`); + } + if (log) console.log(currentmod, "Lien vers options:", optionsfile); + if (!fs.existsSync(optionsfile)) { + propertie.msg = "missingref"; + return propertie; + } else { + delete propertie.options; + if (optionstype == "options") { + propertie.enum = fs.readJSONSync(optionsfile).lst_idx; } - if (propertie.options["$ref"].includes("/idx/")) { - optionstype = "idx"; - optionsfile = path.resolve( - `../../${propertie.options["$ref"]}.json` - ); + if (optionstype == "idx") { + propertie.enum = fs.readJSONSync(optionsfile); } - if (log) console.log(currentmod, "Lien vers options:", optionsfile); - if (!fs.existsSync(optionsfile)) { - propertie.msg = "missingref"; - return propertie; - } else { - delete propertie.options - if (optionstype == "options") { - propertie.enum = - fs.readJSONSync(optionsfile).lst_idx; - } - if (optionstype == "idx") { - propertie.enum = fs.readJSONSync(optionsfile); - } - } - return propertie - } + } + return propertie; + }; if (log) console.log(currentmod, `${objectPathname}/conf.json`); const res = { @@ -274,23 +273,29 @@ Odmdb.Schema = (objectPathname, validschema, lg = "en") => { }; } // get $ref from $def - if (res.data.schema["$defs"]){ - Object.keys(res.data.schema["$defs"]).forEach(ss=>{ - Object.keys(res.data.schema["$defs"][ss].properties).forEach(pp=>{ - res.data.schema["$defs"][ss].properties[pp]=convoptionstoenum(res.data.schema["$defs"][ss].properties[pp],lg) - }) - }) + if (res.data.schema["$defs"]) { + Object.keys(res.data.schema["$defs"]).forEach((ss) => { + Object.keys(res.data.schema["$defs"][ss].properties).forEach((pp) => { + res.data.schema["$defs"][ss].properties[pp] = convoptionstoenum( + res.data.schema["$defs"][ss].properties[pp], + lg + ); + }); + }); } Object.keys(res.data.schema.properties).forEach((p) => { if ( res.data.schema.properties[p].type == "object" && res.data.schema.properties[p]["$ref"] ) { - let subschema - const localdef=res.data.schema.properties[p]["$ref"].includes("#/") + let subschema; + const localdef = res.data.schema.properties[p]["$ref"].includes("#/"); if ( localdef && - !(res.data.schema["$defs"] && res.data.schema["$defs"][propertie["$ref"]]) + !( + res.data.schema["$defs"] && + res.data.schema["$defs"][propertie["$ref"]] + ) ) { res.status = 404; res.msg = "missinglocalref"; @@ -298,21 +303,29 @@ Odmdb.Schema = (objectPathname, validschema, lg = "en") => { return res; } if (localdef) { - res.data.schema.properties[p]=res.data.schema["$defs"][res.data.schema.properties[p]["$ref"]] - }else{ - subschema = Odmdb.Schema(path.resolve(res.data.schema.properties[p]["$ref"]), validschema, lg) - if(subschema.status==200){ - res.data.schema.properties[p]=subschema.data.schema; - }else{ - subschema.data.originschemaproperty=p - return subschema - } + res.data.schema.properties[p] = + res.data.schema["$defs"][res.data.schema.properties[p]["$ref"]]; + } else { + subschema = Odmdb.Schema( + path.resolve(res.data.schema.properties[p]["$ref"]), + validschema, + lg + ); + if (subschema.status == 200) { + res.data.schema.properties[p] = subschema.data.schema; + } else { + subschema.data.originschemaproperty = p; + return subschema; + } } } - if (res.data.schema.properties[p].options){ + if (res.data.schema.properties[p].options) { //remplace options par enum:[] - res.data.schema.properties[p]=convoptionstoenum(res.data.schema.properties[p],lg) - } + res.data.schema.properties[p] = convoptionstoenum( + res.data.schema.properties[p], + lg + ); + } }); if (!res.data.schema.apxid) { @@ -359,24 +372,78 @@ Odmdb.Schema = (objectPathname, validschema, lg = "en") => { } return res; }; -Odmdb.search = (objectPath, objectName, search) => { +Odmdb.search = (objectPathname, objsearch, role) => { /* - @search= { - txt: string, - algo: match | pattern | fuzzy - fieldstring:[list of field], - indexfilter:{index1:[val1,val2 | ] } + if (fields exist): + return data:{id:{field:value}]} + else: + return data:[id] + + exemple: + objsearch= { + apxid:['toto','titi'],fields:['firstname'] } - Return data:[uuids] - + return data:{toto:{firstname:"Paul"},titi:"fistname:"Jacques"} + ADD HERE OTHER OPTION USING IDX FOR PERFORMANCE + example: search exact match hill in townId heavy search={txt:"hill",algo:"match",fieldstring:"toxnId"} light search={txt:"hill", algo:"match", indexfilter:{"key":"townId","value":[]}} light search={txt:"hill", algo:"match", indexfilter:{"key":"nationId","value":"ants"}} */ - const schema = Odmdb.schema(objectPath, objectName); - if (schema.status != 200) return schema; + const getschema = Odmdb.Schema(objectPathname, true); + if (getschema.status != 200) return getschema; + //console.log(getschema.data); + const apxid = getschema.data.apxid; + let subsearch = objsearch.apxid + ? objsearch.apxid + : fs.readJSONSync(`${objectPathname}/idx/lst_${apxid}.json`); + // ADD HERE OTHER FILTRATION SEARCH depending of question + if (objsearch.question) { + // remove or add in subsearch + } + if (objsearch.fields) { + const resultat = {}; + const accessright = Odmdb.accessright( + getschema.data.schema.apxaccessrights, + role + ); + //console.log(accessright); + const ifields={} + subsearch.forEach((i) => { + const ifields = {}; + if (fs.existsSync(`${objectPathname}/itm/${i}.json`)) { + const itm = fs.readJSONSync(`${objectPathname}/itm/${i}.json`); + if (itm.owner && itm.owner == role.xalias) { + role.xprofils.push("owner"); + } + objsearch.fields.forEach((f) => { + if (accessright.R.includes(f)) { + ifields[f] = itm[f]; + } else { + ifields[f] = "unauthorized"; + } + }); + } else { + ifields.notfound = true; + } + resultat[i] = ifields; + }); + return { + status: 200, + ref: "Odmdb", + msg: "resultsearchlist", + data: resultat, + }; + } else { + return { + status: 200, + ref: "Odmdb", + msg: "resultsearchlist", + data: [subsearch], + }; + } }; Odmdb.r = (objectPathname, apxid, role) => { diff --git a/models/Wwws.js b/models/Wwws.js index 49b59d3..9b734e9 100644 --- a/models/Wwws.js +++ b/models/Wwws.js @@ -7,82 +7,155 @@ const Odmdb = require("./Odmdb.js"); const conf = require(`../../../conf.json`); const Wwws = {}; -Wwws.initlocaldata = (tribe, appname, profils,lg) => { +Wwws.initlocaldata = (tribe, appname, pagename, version, profils, lg) => { const fileparam = `../../${tribe}/objects/wwws/itm/${appname}.json`; + console.log(fileparam); if (!fs.existsSync(fileparam)) { - return res - .status(404) - .json({ status: 404, ref: "Wwws", msg: "appdoesnotexist", data: {} }); + return { status: 404, ref: "Wwws", msg: "appdoesnotexist", data: {} }; } const locals = fs.readJSONSync(fileparam); + if (!locals.pages[pagename]) { + return { + status: 200, + ref: "Wwws", + msg: "pagedoesnotexist", + data: { pagename }, + }; + } + if (locals.pages[pagename].version == version) { + return { status: 200, ref: "Wwws", msg: "nonewdatamodel", data: {} }; + } + let authorize = false; + profils.forEach((p) => { + authorize = authorize || locals.pages[pagename].profils.includes(p); + }); + if (!authorize) { + return { + status: 200, + ref: "Wwws", + msg: "forbidenaccess", + data: { pagename, profils }, + }; + } + //check version + const initname = `../../tmp/initlocaldata/${tribe}_${appname}_${pagename}_${lg}_${locals.pages[pagename].version}.json`; + if (fs.existsSync(initname) && 1 != 1) { + const init = fs.readJsonSync(initname); + if (init.app.version == locals.app.version) { + return { status: 200, ref: "Wwws", msg: "datamodelupdate", data: init }; + } + } const localstorage = { - headers: locals.headers, + version: locals.pages[pagename].version, + headers: locals.apxtri.headers, + confpages:locals.pages[pagename].confpage, req: {}, - itm: {}, + itm:{}, itms: {}, options: {}, tpl: {}, + tpldata:{}, ref: {}, schema: {}, }; - localstorage.headers.xlang=lg; - profils.forEach((p) => { - if (locals.profils[p]) { - if (locals.profils[p].req){ - localstorage.req[p] = locals.profils[p].req; + localstorage.headers.xlang = lg; + // A faire plus tard charger tous les referentiele et les data pour une page adminpage + /* if (pagename=="pageadmin"){ + // load any referentialdata + glob.Sync(`../../${tribe}/objects/*.json`).forEach(f=>{ + if (!localstorage.schema.includes(`${tribe}/objects/${path.basename(f,".json")}`)){ + localstorage.schema.push(`${tribe}/objects/${path.basename(f,".json")}`) } - if (locals.profils[p].ref){ - Object.keys(locals.profils[p].ref).forEach(r=>{ - const src= `../../${locals.profils[p].ref[r]}_${lg}.json`; - if (fs.existsSync(src)){ - localstorage.ref[r]=fs.readJSONSync(src) - }else{ - localstorage.ref[r]=`Check your ${fileparam} for ref in ${p} and ${r}` - } - }) + }) + + } + */ + const loc = locals.pages[pagename]; + if (loc.itms){ + Object.keys(loc.itms).forEach((r) => { + const src = `../../${loc.itms[r]}.json`; + if (fs.existsSync(src)) { + localstorage.itms[r] = fs.readJSONSync(src); + } else { + localstorage.itms[r] = `Check your ${fileparam} for itms in ${pagename} and ${r}`; } - if (locals.profils[p].options){ - Object.keys(locals.profils[p].options).forEach(r=>{ - const src= `../../${locals.profils[p].options[r]}_${lg}.json`; - if (fs.existsSync(src)){ - localstorage.options[r]=fs.readJSONSync(src) - }else{ - localstorage.options[r]=`Check your ${fileparam} for options in ${p} profil and ${r}` - } - }) + }); + } + if (loc.ref) { + Object.keys(loc.ref).forEach((r) => { + const src = `../../${loc.ref[r]}_${lg}.json`; + if (fs.existsSync(src)) { + localstorage.ref[r] = fs.readJSONSync(src); + } else { + localstorage.ref[ + r + ] = `Check your ${fileparam} for ref in ${pagename} and ${r}`; } - if (locals.profils[p].tpl){ - Object.keys(locals.profils[p].tpl).forEach(r=>{ - let src= `../../${locals.profils[p].tpl[r]}`; - if (!fs.existsSync(src)){ - src+=`_${lg}.mustache` - } - if (fs.existsSync(src)){ - localstorage.tpl[r]=fs.readJSONSync(src) - }else{ - localstorage.tpl[r]=`Check your ${fileparam} for template in ${p} profil and ${r}` - } - }) + }); + } + if (loc.options) { + Object.keys(loc.options).forEach((r) => { + const src = `../../${loc.options[r]}_${lg}.json`; + if (fs.existsSync(src)) { + localstorage.options[r] = fs.readJSONSync(src); + } else { + localstorage.options[ + r + ] = `Check your ${fileparam} for options in ${pagename} profil and ${r}`; } - if (locals.profils[p].schema){ - locals.profils[p].schema.forEach(objpath=>{ - const name=path.basename(objpath) - const schema=Odmdb.Schema(`../../${objpath}`,false,lg) - if (schema.status==200){ - localstorage.schema[name]=schema.data.schema - }else{ - console.log(schema) - localstorage.schema[name]=`Check your ${fileparam} for schema in ${p} profil` - } - }) + }); + } + if (loc.tpl) { + Object.keys(loc.tpl).forEach((r) => { + let src = `../../${loc.tpl[r]}`; + console.log(path.resolve(src)) + if (!fs.existsSync(src)) { + src += `_${lg}.mustache`; } - } - }); + if (fs.existsSync(src)) { + localstorage.tpl[r] = fs.readFileSync(src,'utf-8'); + } else { + localstorage.tpl[ + r + ] = `Check your ${fileparam} for template in ${pagename} profil and ${r}`; + } + }); + } + if (loc.tpldata) { + Object.keys(loc.tpldata).forEach((r) => { + let src = `../../${loc.tpldata[r]}`; + console.log(path.resolve(src)) + if (!fs.existsSync(src)) { + src += `_${lg}.json`; + } + if (fs.existsSync(src)) { + localstorage.tpldata[r] = fs.readJSONSync(src); + } else { + localstorage.tpldata[ + r + ] = `Check your ${fileparam} for template in ${pagename} profil and ${r} in tpldata`; + } + }); + } + if (loc.schema) { + loc.schema.forEach((objpath) => { + const name = path.basename(objpath); + const schema = Odmdb.Schema(`../../${objpath}`, false, lg); + if (schema.status == 200) { + localstorage.schema[name] = schema.data.schema; + } else { + console.log(schema); + localstorage.schema[ + name + ] = `Check your ${fileparam} for schema in ${pagename} profil`; + } + }); + } return { status: 200, ref: "Wwws", - msg: "initdbsuccess", - data: { localstorage }, + msg: "datamodelupdate", + data: localstorage }; }; diff --git a/routes/odmdb.js b/routes/odmdb.js index ea9c9cb..4250489 100644 --- a/routes/odmdb.js +++ b/routes/odmdb.js @@ -9,11 +9,11 @@ const checkHeaders = require("../middlewares/checkHeaders.js"); const isAuthenticated = require("../middlewares/isAuthenticated.js"); const router = express.Router(); -/** +/** * @api {get} /adminapi/odmdb/schemas/:tribe - objects Get * @apiGroup Odmdb * @apiName getIndex - * @apiDescription Get objects available result is store in data.apx.conf for schema conf of adminapi schema (pagans,towns,... ) and data.apx.objectnames as array of schema name. Schema related to tribe are store in data.tribe.conf and data.tribe.objectnames where tribe come from header.xtribe + * @apiDescription Get objects available result is store in data.apx.conf for schema conf of adminapi schema (pagans,towns,... ) and data.apx.objectnames as array of schema name. Schema related to tribe are store in data.tribe.conf and data.tribe.objectnames where tribe come from header.xtribe * @apiParams {string} tribe to get list of schema related to tribe * @apiSuccess {object} contain data.indexname * @apiSuccessExample {json} Success-Response: @@ -26,25 +26,25 @@ router.get("/schemas/:tribe", checkHeaders, isAuthenticated, (req, res) => { apx: { conf: {}, objectnames: [] }, tribe: { conf: {}, objectnames: [] }, }; - let trb - glob.sync(`..{/,/../${req.params.tribe}/}schema/*.json`).forEach(f=>{ - const objectname=path.basename(f,".json"); - console.log(f) - trb = (f.includes(req.params.tribe))? "tribe":"apx"; + let trb; + glob.sync(`..{/,/../${req.params.tribe}/}schema/*.json`).forEach((f) => { + const objectname = path.basename(f, ".json"); + console.log(f); + trb = f.includes(req.params.tribe) ? "tribe" : "apx"; if (objectname == "conf") { data[trb].conf = fs.readJSONSync(f); } else { data[trb].objectnames.push(objectname); } - }) + }); res.status(200).json({ status: 200, ref: "Odmdb", msg: "objectslist", data }); }); -/** +/** * @api {get} /adminapi/odmdb/schema/:tribe/:objectname - Schema Get in the language header * @apiGroup Odmdb * @apiName getIndex - * @apiDescription Get schema in the requested language if login have accessright. object $ref or $id are replace by the relevant schema, option $ref are replace by enum list of authorised value - * + * @apiDescription Get schema in the requested language if login have accessright. object $ref or $id are replace by the relevant schema, option $ref are replace by enum list of authorised value + * * @apiParams {string} tribe (adminapi,smatchit,..) to looking for * @apiParams {string} objectname requested must exist in adminapi or tribe * @apiSuccess {object} contain data.schema @@ -52,19 +52,24 @@ router.get("/schemas/:tribe", checkHeaders, isAuthenticated, (req, res) => { * HTTP/1.1 200 OK * {"status":200, "ref":"Odmdb", "msg":"schema", "data":{schema,objectname,lg} */ -router.get("/schema/:tribe/:objectname", checkHeaders, isAuthenticated, (req, res) => { - const objectPathname=`../../${req.params.tribe}/objects/${req.params.objectname}` - console.log(objectPathname) - const retschema = Odmdb.Schema(objectPathname, true, req.header.xlang) - res.status(retschema.status).json(retschema); -}); +router.get( + "/schema/:tribe/:objectname", + checkHeaders, + isAuthenticated, + (req, res) => { + const objectPathname = `../../${req.params.tribe}/objects/${req.params.objectname}`; + console.log(objectPathname); + const retschema = Odmdb.Schema(objectPathname, true, req.header.xlang); + res.status(retschema.status).json(retschema); + } +); -/** +/** * @api {get} /adminapi/odmdb/options/:tribe/objects/option/:optionname - Get option list in header language * @apiGroup Odmdb * @apiName getOption - * @apiDescription Get schema in the requested language if login have accessright. object $ref or $id are replace by the relevant schema, option $ref are replace by enum list of authorised value - * + * @apiDescription Get schema in the requested language if login have accessright. object $ref or $id are replace by the relevant schema, option $ref are replace by enum list of authorised value + * * @apiParams {string} tribe (adminapi,smatchit,..) to looking for * @apiParams {string} objectname requested must exist in adminapi or tribe * @apiSuccess {object} contain data.schema @@ -72,24 +77,43 @@ router.get("/schema/:tribe/:objectname", checkHeaders, isAuthenticated, (req, re * HTTP/1.1 200 OK * {"status":200, "ref":"Odmdb", "msg":"schema", "data":{schema,objectname,lg} */ -router.get("/options/:tribe/objects/option/:optionname", checkHeaders, isAuthenticated, (req, res) => { - const objectPathname=`../../${req.params.tribe}/objects/options/${req.params.optionname}_${req.header.xlang}.json` - if (fs.existsSync(objectPathname)){ - res.status(200).json({status:200,ref:"Odmdb",msg:"optionfind",data:fs.readJsonSync(objectPathname)}) - }else{ - res.status(404).json({status:404,ref:"Odmdb",msg:"optionnotfound",data:{objectPathname}}) +router.get( + "/options/:tribe/objects/option/:optionname", + checkHeaders, + isAuthenticated, + (req, res) => { + const objectPathname = `../../${req.params.tribe}/objects/options/${req.params.optionname}_${req.header.xlang}.json`; + if (fs.existsSync(objectPathname)) { + res + .status(200) + .json({ + status: 200, + ref: "Odmdb", + msg: "optionfind", + data: fs.readJsonSync(objectPathname), + }); + } else { + res + .status(404) + .json({ + status: 404, + ref: "Odmdb", + msg: "optionnotfound", + data: { objectPathname }, + }); + } } -}); +); /** - * @api {get} /adminapi/odmdb/idx/:tribe/:objectname/:indexname - index Get + * @api {get} /api/adminapi/odmdb/idx/:tribe/:objectname/:indexname - index Get * @apiGroup Odmdb - * @apiName getIndex + * @apiName getIndexbyindexname * @apiDescription Get index file for an object * - * @apiParam {string} tribe if common adminapi or tribename - * @apiParam {string} objectname If in conf.nationObjects then object is into nationchains/ else in tribes/xtribe/objectname/idx/indexname indexname - * @apiParam {String} indexname name of index file in /idx/indexnamme.json + * @apiParams {string} tribe if common adminapi or tribename + * @apiParams {string} objectname If in conf.nationObjects then object is into nationchains/ else in tribes/xtribe/objectname/idx/indexname indexname + * @apiParams {String} indexname name of index file in /idx/indexnamme.json * * * @apiError {json} objectNotfound the file does not exist @@ -101,8 +125,6 @@ router.get("/options/:tribe/objects/option/:optionname", checkHeaders, isAuthent * @apiSuccessExample {json} Success-Response: * HTTP/1.1 200 OK * {"status":200, "ref":"Odmdb", "msg":"indexexist", "data":{indexname,content:{index file}} - * - * */ router.get( "/idx/:tribe/:objectname/:indexname", @@ -111,6 +133,7 @@ router.get( (req, res) => { console.log("passe"); const indexpath = `../../${req.params.tribe}/objects/${req.params.objectname}/idx/${req.params.indexname}`; + console.log(indexpath); if (fs.existsSync(indexpath)) { res.status(200).json({ ref: "Odmdb", @@ -157,7 +180,7 @@ router.get( console.log("reindex"); // check validity and accessright - const objectPathname=`../../${req.params.tribe}/objects/${req.params.objectname}` + const objectPathname = `../../${req.params.tribe}/objects/${req.params.objectname}`; if (!fs.existsSync(objectPathname)) { res.status(404).json({ status: 404, @@ -223,14 +246,21 @@ router.get( * {"status":404,"ref":"Odmdb","msg":"see nationchains/model/lg/Odmdb_xx.json","data":"object to render with msg"} * */ -router.post("/itm/:tribe/:objectname", checkHeaders, isAuthenticated, (req, res) => { - // Create an item of an object with no specificities - // if specificities then create a route / model that import odmdb - const objectPathname=`../../${req.params.tribe}/objects/${req.params.objectname}`; - const postitm=Odmdb.cud(objectPathname,"C",req.body,{xprofils:req.session.header.xprofils,xalias:req.session.header.xalias}); - res.status(postitm.status).json(postitm); -}); - +router.post( + "/itm/:tribe/:objectname", + checkHeaders, + isAuthenticated, + (req, res) => { + // Create an item of an object with no specificities + // if specificities then create a route / model that import odmdb + const objectPathname = `../../${req.params.tribe}/objects/${req.params.objectname}`; + const postitm = Odmdb.cud(objectPathname, "C", req.body, { + xprofils: req.session.header.xprofils, + xalias: req.session.header.xalias, + }); + res.status(postitm.status).json(postitm); + } +); /** * @api {put} /adminapi/odmdb/itm/:tribe/:objectname - item Update @@ -259,13 +289,21 @@ router.post("/itm/:tribe/:objectname", checkHeaders, isAuthenticated, (req, res) * {"status":404,"ref":"Odmdb","msg":"see nationchains/model/lg/Odmdb_xx.json","data":"object to render with msg"} * */ -router.put("/itm/:tribe/:objectname", checkHeaders, isAuthenticated, (req, res) => { - // Create an item of an object with no specificities - // if specificities then create a route / model that import odmdb - const objectPathname=`../../${req.params.tribe}/objects/${req.params.objectname}`; - const postitm=Odmdb.cud(objectPathname,"U",req.body,{xprofils:req.session.header.xprofils,xalias:req.session.header.xalias}); - res.status(postitm.status).json(postitm); -}); +router.put( + "/itm/:tribe/:objectname", + checkHeaders, + isAuthenticated, + (req, res) => { + // Create an item of an object with no specificities + // if specificities then create a route / model that import odmdb + const objectPathname = `../../${req.params.tribe}/objects/${req.params.objectname}`; + const postitm = Odmdb.cud(objectPathname, "U", req.body, { + xprofils: req.session.header.xprofils, + xalias: req.session.header.xalias, + }); + res.status(postitm.status).json(postitm); + } +); /** * @api {delete} /adminapi/odmdb/itm/:tribe/:objectname/:primaryid - item Delete @@ -293,31 +331,42 @@ router.put("/itm/:tribe/:objectname", checkHeaders, isAuthenticated, (req, res) * {"status":404,"ref":"Odmdb","msg":"see nationchains/model/lg/Odmdb_xx.json","data":"object to render with msg"} * */ -router.put("/itm/:tribe/:objectname", checkHeaders, isAuthenticated, (req, res) => { - // Create an item of an object with no specificities - // if specificities then create a route / model that import odmdb - const objectPathname=`../../${req.params.tribe}/objects/${req.params.objectname}`; - const postitm=Odmdb.cud(objectPathname,"U",req.body,{xprofils:req.session.header.xprofils,xalias:req.session.header.xalias}); - res.status(postitm.status).json(postitm); -}); - +router.put( + "/itm/:tribe/:objectname", + checkHeaders, + isAuthenticated, + (req, res) => { + // Create an item of an object with no specificities + // if specificities then create a route / model that import odmdb + const objectPathname = `../../${req.params.tribe}/objects/${req.params.objectname}`; + const postitm = Odmdb.cud(objectPathname, "U", req.body, { + xprofils: req.session.header.xprofils, + xalias: req.session.header.xalias, + }); + res.status(postitm.status).json(postitm); + } +); /** * @api {post} /adminapi/odmdb/searchitms/:tribe/:objectname - items Search * @apiGroup Odmdb - * @apiName searchItm + * @apiName searchItms * @apiPermission none - * @apiDescription Search in an object collection of items - * @apiParam {string} tribe adminapi or tribe name (smatchit), where object is store + * @apiDescription Search dynamicaly in an object collection of items, results can be a list of apxid or an object {apxid1:{propertie:value,..}}. To get object you must specify in body the key fields. See usage example. TODO: This will evolve with deeper search technics + * @apiParam {string} tribe name (smatchit), where object is store * @apiParam {string} objectname object name where looking for - * @apiBody {array} fields list of properties at least apxid propertie - * @apiBody {string} question a specific syntaxe to find quickly items by using index litteral text @TODO : create a query syntaxe... + * @apiBody {array} [apxid] list of apxid prefilter when for perfomance you want filter the search investigation. If omit then it is looking for in any item object + * @apiBody {array} [fields] list of properties of object you want to get (profils user must have accessright in Read for those fields, a value 'unauthorized' can be return in this case) + * @apiBody {string} [question] a specific syntaxe to find quickly items by using index litteral text @TODO : create a query syntaxe for a question... * - * @apiSuccess {json} contain a json file + * @apiSuccess {json} contain {status,ref,msg,data} * @apiSuccessExample {json} Success-Response: - * HTTP/1.1 200 OK - * {"status":200, "ref":"Odmdb", "msg":"searchresult", "data":{"itms":[{itm fields}]}} - * @apiError {json} objectdoesnotexist the obbject does not exist for the tribe + * HTTP/1.1 200 OK from {apxid:[itmid],fields:[field1,field2]} + * {"status":200, "ref":"Odmdb", "msg":"searchresult", "data":{"itms":{itmid:{field1,field2}]}} + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK from {question:} + * {"status":200, "ref":"Odmdb", "msg":"searchresult", "data":[itm1,itm2]} + * @apiError {json} objectdoesnotexist the obbject does not exist for the tribe * @apiError {json} unconsistentquestion the question format is not relevant * @apiErrorExample {json} * HTTP/1.1 404 Not Found @@ -325,12 +374,16 @@ router.put("/itm/:tribe/:objectname", checkHeaders, isAuthenticated, (req, res) * */ router.post( - "/searchitems/:objectname/:question", + "/searchitms/:tribe/:objectname", checkHeaders, isAuthenticated, (req, res) => { - // voir comment sortir isAuthenticated poure autoriser l'acces au search sur des object plublic - res.status(200).json({status:200,ref:"Odmdb",msg:"TODO",data:{}}) + const objectPathname = `../../${req.params.tribe}/objects/${req.params.objectname}`; + const ressearch = Odmdb.search(objectPathname, req.body, { + xprofils: req.session.header.xprofils, + xalias: req.session.header.xalias, + }); + res.status(ressearch.status).json(ressearch); } ); @@ -346,7 +399,7 @@ router.post( * @apiError {json} objectfiledoesnotexist the file item does not exist * @apiErrorExample {json} * HTTP/1.1 404 Not Found - * {status:404,ref: "Odmdb",msg: "objectfiledoesnotexist",data: { objectpath }} + * {status:404,ref: "Odmdb",msg: "objectfiledoesnotexist",data: { objectpath }} * @apiSuccess {object} indexfile content * @apiSuccessExample {json} Success-Response: * HTTP/1.1 200 OK @@ -362,10 +415,17 @@ router.get( const objectpath = `../../${req.params.tribe}/objects/${req.params.objectname}/itm/${req.params.primaryindex}.json`; if (fs.existsSync(objectpath)) { - res.status(200).json({status:200,ref:"Odmdb",msg:"itmfound", data:fs.readJsonSync(objectpath) }); + res + .status(200) + .json({ + status: 200, + ref: "Odmdb", + msg: "itmfound", + data: fs.readJsonSync(objectpath), + }); } else { res.status(404).json({ - status:404, + status: 404, ref: "Odmdb", msg: "objectfiledoesnotexist", data: { objectpath }, diff --git a/routes/wwws.js b/routes/wwws.js index 094d016..6723c64 100644 --- a/routes/wwws.js +++ b/routes/wwws.js @@ -10,29 +10,123 @@ const isAuthenticated = require("../middlewares/isAuthenticated"); const router = express.Router(); // GET api/wwws/conf/:tribeId/:website // if profils accessright return the nginx conf in ${conf.dirtown}/tribes/${req.param.tribeId}/www/nginx_${req.params.tribeId}_${req.params.website}.conf -router.get("/conf/:tribeId/:website", checkHeaders, isAuthenticated, (req, res) => { - res.send(Www.configlist(req.params.tribeId)); -}); -router.post("/conf/:tribeId/:website", checkHeaders, isAuthenticated, (req, res) => { - res.send(Wwws.create(req.params.tribeId)); -}); -/** - * @api {get} /adminapi/wwws/initlocaldb/:tribe/:appname - Get app data model +router.get( + "/conf/:tribeId/:website", + checkHeaders, + isAuthenticated, + (req, res) => { + res.send(Www.configlist(req.params.tribeId)); + } +); +router.post( + "/conf/:tribeId/:website", + checkHeaders, + isAuthenticated, + (req, res) => { + res.send(Wwws.create(req.params.tribeId)); + } +); + + +/** + * @api {get} /api/adminapi/wwws/updatelocaldbanonymous/:tribe/:appname/:pagename/:version - Get app data model for anonymous only * @apiGroup Wwws * @apiName getappcontext - * @apiDescription Get data base from backend to localstorage - * + * @apiDescription Get data base from backend to localstorage + * * @apiParams {string} tribe (adminapi,smatchit,..) to looking for * @apiParams {string} appname agregate a full data referential to store localy - * @apiSuccess {object} contain data model for a local web or mobile app in a PWA logical in the language of the header + * @apiParams {string} pagename app page name + * @apiParams {interger} version the current version + * @apiSuccess {object} contain new version data model for a local web app in a PWA logical in the language of the header or if no new version exist then return * @apiSuccessExample {json} Success-Response: * HTTP/1.1 200 OK - * {"status":200, "ref":"Odmdb", "msg":"datamodel", "data":{} + * {"status":200, "ref":"Odmdb", "msg":"datamodelupdate", "data":{version,conpages,profils,...}} + * {"status":200, "ref":"Odmdb", "msg":"nonewdatamodel", "data":{}} */ -router.get("/initlocaldb/:tribe/:appname", checkHeaders, isAuthenticated, (req, res) => { - console.log('pass localstorage') - const getlocal = Wwws.initlocaldata(req.params.tribe,req.params.appname,req.session.header.xprofils,req.session.header.xlang); - res.status(getlocal.status).json(getlocal) +router.get( + "/updatelocaldbanonymous/:tribe/:appname/:pagename/:version", + checkHeaders, + (req, res) => { + console.log("pass localstorage anonymous", req.session.header.xalias); + req.session.header.xprofils = ["anonymous"]; + console.log(req.session.header.xprofils); + //ajouter une detection de changement + const getlocal = Wwws.initlocaldata( + req.params.tribe, + req.params.appname, + req.params.pagename, + req.params.version, + req.session.header.xprofils, + req.session.header.xlang + ); + res.status(getlocal.status).json(getlocal); + } +); + +/** + * @api {get} /api/adminapi/wwws/updatelocaldb/:tribe/:appname/:pagename/:version - Get app data model + * @apiGroup Wwws + * @apiName getappcontext + * @apiDescription Get data base from backend to localstorage + * + * @apiParams {string} tribe (adminapi,smatchit,..) to looking for + * @apiParams {string} appname agregate a full data referential to store localy + * @apiParams {string} pagename app page name + * @apiParams {interger} version the current version + * @apiSuccess {object} contain new version data model for a local web app in a PWA logical in the language of the header or if no new version exist then return + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * {"status":200, "ref":"Odmdb", "msg":"datamodelupdate", "data":{version,conpages,profils,...}} + * {"status":200, "ref":"Odmdb", "msg":"nonewdatamodel", "data":{}} + */ +router.get( + "/updatelocaldb/:tribe/:appname/:pagename/:version", + checkHeaders, isAuthenticated, + (req, res) => { + console.log("pass localstorage", req.session.header.xalias); + console.log(req.session.header.xprofils); + //ajouter une detection de changement + const getlocal = Wwws.initlocaldata( + req.params.tribe, + req.params.appname, + req.params.pagename, + req.params.version, + req.session.header.xprofils, + req.session.header.xlang + ); + res.status(getlocal.status).json(getlocal); + } +); +/** + * @api {get} /api/adminapi/wwws/buildpage/:tribe/:appname/:pagename - Create pagename + * @apiGroup Wwws + * @apiName createPagename + * @apiDescription Create a pagename from /appscreen/template/:pagename with + * + * @apiParams {string} tribe (adminapi,smatchit,..) to looking for + * @apiParams {string} appname agregate a full data referential to store localy + * @apiSuccess {object} contain cuurent version of the data model + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * {"status":200, "ref":"Odmdb", "msg":"datamodelversion", "data":{version} + */ +router.get("/buildpage/:tribe/:appname/:pagename", checkHeaders, (req, res) => { + console.log("pass get version localstorage"); + const localdbf = `../../${req.params.tribe}/objects/wwws/itm/${req.params.appname}`; + if (!existsSync(localdbf)) { + return res + .status(404) + .json({ status: 404, ref: "Wwws", msg: "localdbnotfound", data: {} }); + } + res + .status(200) + .json({ + status: 200, + ref: "Wwws", + msg: "lastversion", + data: { version: fs.readJSONSync(localdbf).version }, + }); }); module.exports = router;