From 1473f07e3dae67ba668fd823e55e4720ee01769b Mon Sep 17 00:00:00 2001 From: philc Date: Tue, 25 Feb 2025 12:24:55 +0100 Subject: [PATCH] device tracking --- apxtri/models/Wwws.js | 4 + apxtri/routes/pagans.js | 2 +- apxtri/routes/trackings.js | 74 +++++++++++++++-- schema/devices.json | 165 +++++++++++++++++++++++++------------ 4 files changed, 184 insertions(+), 61 deletions(-) diff --git a/apxtri/models/Wwws.js b/apxtri/models/Wwws.js index bc0c65f..862168f 100644 --- a/apxtri/models/Wwws.js +++ b/apxtri/models/Wwws.js @@ -43,6 +43,9 @@ Wwws.getwco = (wconame, ctx) => { //check in ctx.wcotribe if ctx.tribe_ctx.code exist in console.log("@todo don't forget to manage accessright to wco in Wwws"); //check that all tpl, tpldata, ... are available for this pagename + if (wconame=="tracker" && !fs.pathExistsSync(`../${ctx.tribe}/objects/wwws/cdn/log`)){ + fs.cpSync(`../adminapi/objects/wwws/cdn/log ../${ctx.tribe}/objects/wwws/cdn/`) + } const webconf = `../${ctx.tribe}/objects/wwws/itm/${ctx.xapp}.json`; const webpageinit = { dns: [], @@ -77,6 +80,7 @@ Wwws.getwco = (wconame, ctx) => { ref: {}, schema: [], tpldata: {}, + wco:{} }; const wcoinfo = fs.readJSONSync(wcoconf); const webpage = fs.existsSync(webconf) diff --git a/apxtri/routes/pagans.js b/apxtri/routes/pagans.js index 03e8179..2cbc608 100755 --- a/apxtri/routes/pagans.js +++ b/apxtri/routes/pagans.js @@ -10,7 +10,7 @@ const checkHeaders = require("../middlewares/checkHeaders.js"); const isAuthenticated = require("../middlewares/isAuthenticated.js"); const conf = require(`../../../adminapi/objects/tribes/itm/adminapi.json`); -const currentmod = "pagans"; +const currentmod = "Pagans"; const log = conf.api.activelog.includes(currentmod); const router = express.Router(); diff --git a/apxtri/routes/trackings.js b/apxtri/routes/trackings.js index 7f5d1b0..425a38f 100644 --- a/apxtri/routes/trackings.js +++ b/apxtri/routes/trackings.js @@ -3,6 +3,8 @@ const glob = require("glob"); const fs = require("fs-extra"); const path = require("path"); const conf = require(`../../../adminapi/objects/tribes/itm/adminapi.json`); +const currentmod="Trackings" +const log = conf.api.activelog.includes(currentmod); const Odmdb = require("../models/Odmdb.js"); // Middlewares const checkHeaders = require("../middlewares/checkHeaders"); @@ -10,6 +12,68 @@ const isAuthenticated = require("../middlewares/isAuthenticated"); const router = express.Router(); +/** + * @api {post} adminapi/trackings/newdevice - Post new device + * @apiName adddevice + * @apiGroup Trackings + * @apiDescription + * Create a device from a xuuid wco tracker.js with information about the device. It is suppose to be a new device but if xuuid already exist then it will be update with new information + * @apiBody {object} device see schema/adminapi/schema/device.json + * + * @apiError {json} objectNotfound the file does not exist + * @apiErrorExample {json} + * HTTP/1.1 406 Not Acceptable + {"status":406,"ref":"Trackings","multimsg":{},"data":{body}} + * + * @apiSuccessExample {json} Success-create: + * HTTP/1.1 200 OK + * {"status":200, "ref":"Trackings", "msg":"successfullcreate", "data":{}} + * @apiSuccessExample {json} Success-update: + * HTTP/1.1 200 OK + * {"status":200, "ref":"Trackings", "msg":"successfullupdate", "data":{}} + */ + router.post("/newdevice", checkHeaders, async (req, res) => { + if (log) console.log(currentmod, "post new device with", req.body); + const newdevice= {status: 200, + ref: "Trackings", + msg: "success", + data: {}, + }; + const role = { + xalias: req.session.header.xalias, + xprofils: req.session.header.xprofils, + }; + const devicepath=`../${req.session.header.xtribe}/objects/devices/itm/${req.session.header.xuuid}.json`; + const device=req.body; + device.xuuid=req.session.header.xuuid + if (req.session.header.xalias!="anonymous"){ + device.alias=req.session.header.xalias + } + if (await fs.pathExists(devicepath)){ + const updatedevice=Odmdb.cud(`../${req.session.header.xtribe}/objects/devices`,"U",device,role); + if (updatedevice.status==200){ + newdevice.msg="successfullupdate" + }else{ + newdevice.status=updatedevice.status + newdevice.msg=updatedevice.msg + newdevice.data=updatedevice.data + if (updatedevice.multimsg) newdevice.multimsg=updatedevice.multimsg + } + }else{ + const createdevice = Odmdb.cud(`../${req.session.header.xtribe}/objects/devices`,"C",device,role); + console.log(createdevice) + if (createdevice.status==200) { + newdevice.msg="successfullcreate" + }else{ + newdevice.status=createdevice.status + newdevice.msg=createdevice.msg + newdevice.data=createdevice.data + if (createdevice.multimsg) newdevice.multimsg=createdevice.multimsg + } + } + res.status(newdevice.status).json(newdevice); + }); + /** * @api {get} https://dns.xx/trk/pathtofile? - tracking system * @apiGroup Trackings @@ -26,8 +90,8 @@ const router = express.Router(); * * where pathtofile is a ressource accessible from https://dns.xx/pathtofile * For dummy pathtofile for apxtri project, you have:
- * /cdn/log/1x1.png (a 1pixel image 95 bytes ) - * /cdn/log/empty.json (an empty jason 2 bytes) + * /cdn/trkret/1x1.png (a 1pixel image 95 bytes ) + * /cdn/trkret/empty.json (an empty jason 2 bytes) * * html usage to track a loading page or email when a picture is load * using apxwebapp in /src/ we got: @@ -35,10 +99,10 @@ const router = express.Router(); * * in js action: * - * + * * * To hit an eventlistener
- * axios.get("https://dns.xx/trk/cdn/empty.json?alias=anonymous&uuid=1b506f71-1bff-416c-9057-cb8b86296f60&srckey=btnregister&version=1"); + * axios.get("https://dns.xx/trk/cdn/trkret/empty.json?alias=anonymous&uuid=1b506f71-1bff-416c-9057-cb8b86296f60&srckey=btnregister&version=1"); * * If no js available (example:email or pdf document)
* < img src="https://dns.xx/trk/static/img/photo.jpg?alias=anonymous&uuid=1b506f71-1bff-416c-9057-cb8b86296f60&srckey=loadpage&version=1" @@ -69,6 +133,4 @@ const router = express.Router(); */ - - module.exports=router; \ No newline at end of file diff --git a/schema/devices.json b/schema/devices.json index 65ac7c6..3c2ba59 100644 --- a/schema/devices.json +++ b/schema/devices.json @@ -1,71 +1,128 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "adminapi/schema/wco", - "title": "web components", - "description": "A web component wco is a folder with list of mustache and one name.js that deal all the business logic", + "$id": "adminapi/schema/devices", + "title": "Following xuuid", + "description": "xuuid is a unique id that is created for tracking purpose it collect some information about a device mobile, pc,... and a xuuid is generated the first time a domain name is access this is why this information is store into a tribes", "type": "object", "properties": { - "wconame": { - "description": "Folder name into a tribeId/objects/wco/itm", - "title": "Web component reusable in web project based with tailwindcss", + "xuuid": { + "description": "A unique id that is created for a device the first time a user access a domainname", + "title": "Unique id into a browser", "type": "string" }, "owner": { - "description": "owner that earn some fees", + "title": "Owner of this person", + "description": "For accessright purpose this is always equal as alias", "type": "string" }, - "codehash": { - "description": "Code signature of alias publickey", + "dt_create": { + "title": "Creation date", + "type": "string", + "format": "date-time" + }, + "dt_update": { + "type": "string", + "format": "date-time" + }, + "alias": { + "description": "If knowns we get an alias", "type": "string" }, - "thumbnail":{ - "title":"Thumbnail of the component", - "type":"string" + "hits": { + "title": "List of hit of 10 minutes", + "description": "not yet formalize {dns:[{tm: timestamp of the event, trk: srctrk, context of the trk}]", + "type": "object" }, - "title":{ - "title":"Short description of the wco", - "type":"string" + "useragent": { + "title": "user agent the first time", + "type": "string" }, - "description":{ - "title":"Long description in html of the component", - "type":"string" + "typedevice": { + "title": "Type of device", + "type": "string", + "enum": [ + "ipad", + "iphone", + "ipod", + "android", + "PC", + "" + ] }, - "tpl":{ - "description":"list of mustache template to manage components each file must ended by _xx.mustache where xx is the language of the template, so you can add translation easily", - "type":"array" + "os": { + "title": "OS detected", + "type": "string", + "enum": [ + "mobile", + "windows", + "mac", + "linux","" + ] }, - "tpldata":{ - "description":"Example of tpldata that you have to add in your local to customize the wco ended by _xx.json where xx is the language of the template", - "type":"array" + "ip": { + "title": "Public IP from api https://ipinfo.io/json", + "type": "string" + }, + "city": { + "title": "city from ipinfo.io", + "type": "string" + }, + "country": { + "title": "country from ipinfo.io", + "type": "string" + }, + "screenWidth": { + "title": "Screen width of the device", + "type": "integer" + }, + "screenHeight": { + "title": "Screen height of the device", + "type": "integer" + }, + "connection": { + "title": "Bandwidth of thefirst access, this can of course change", + "type": "string" + }, + "lang": { + "title": "Language setting of the device", + "type": "string" + }, + "plugins": { + "title": "List of current plugins install into the browser during the first access", + "type": "array" } -}, -"required": [ -"wconame", -"owner", -"title" -], -"apxid": "wconame", -"apxuniquekey": [ -"wconame" -], -"apxidx": [ -{ - "name": "lst_wconame", - "type": "array", - "keyval": "wconame" -} -], -"apxaccessrights": { -"owner": { - "D": [], - "R": [], - "U": [] -}, -"mayor": { - "C": [] -}, -"person": { - "R": [] -} -} + }, + "required": [ + "xuuid" + ], + "apxid": "xuuid", + "apxuniquekey": [ + "xuuid" + ], + "apxidx": [ + { + "name": "alias", + "type": "view", + "keyval": "alias", + "objkey": [ + "xuuid", + "type", + "os" + ], + "filter": "" + } + ], + "apxaccessrights": { + "anonymous":{ + "C":[], + "U":[], + "D":[] + }, + "mayor": { + "R": [] + }, + "person": { + "R": [] + } + } } \ No newline at end of file