wwws webcomponent wco implementation

This commit is contained in:
philc 2025-01-23 10:24:14 +01:00
parent 11887bb95f
commit 7c92d5521e
7 changed files with 372 additions and 124 deletions

View File

@ -156,7 +156,9 @@ apxtri.setuptribe = async (tribe, conf) => {
// check nginx conf and eventually change if not starting by user "current user"; // check nginx conf and eventually change if not starting by user "current user";
let etcnginx = fs.readFileSync("/etc/nginx/nginx.conf", "utf8"); let etcnginx = fs.readFileSync("/etc/nginx/nginx.conf", "utf8");
let newnginxconf=false
if (etcnginx.split("\n")[0] !== `user ${inittribe.sudoUser};`) { if (etcnginx.split("\n")[0] !== `user ${inittribe.sudoUser};`) {
newnginxconf=true;
inittribe.mainpath = inittribe.townpath.replace( inittribe.mainpath = inittribe.townpath.replace(
`/${inittribe.townId}-${inittribe.nationId}`, `/${inittribe.townId}-${inittribe.nationId}`,
"" ""
@ -196,7 +198,8 @@ apxtri.setuptribe = async (tribe, conf) => {
: fs.readJSONSync("../adminapi/apxtri/setup/initadminapi.json").nginx : fs.readJSONSync("../adminapi/apxtri/setup/initadminapi.json").nginx
.restart; .restart;
const { exec } = require("child_process"); const { exec } = require("child_process");
exec(`sudo mv /tmp/nginx.conf /etc/nginx/nginx.conf && ${nginxrestart}`, (error, stdout, stderr) => { const nginxconfmv = newnginxconf ? "sudo mv /tmp/nginx.conf /etc/nginx/nginx.conf && ":"";
exec(`${nginxconfmv}${nginxrestart}`, (error, stdout, stderr) => {
if (error) { if (error) {
console.log("\x1b[42m", error, stdout, stderr, "x1b[0m"); console.log("\x1b[42m", error, stdout, stderr, "x1b[0m");
process.exit(0); process.exit(0);

View File

@ -3,7 +3,7 @@ const path = require("path");
const fs = require("fs-extra"); const fs = require("fs-extra");
const axios = require("axios"); const axios = require("axios");
const dayjs = require("dayjs"); const dayjs = require("dayjs");
const Mustache = require('mustache'); const Mustache = require("mustache");
const Checkjson = require(`./Checkjson.js`); const Checkjson = require(`./Checkjson.js`);
//const smtp = require("smtp-client"); //const smtp = require("smtp-client");
const nodemailer = require("nodemailer"); const nodemailer = require("nodemailer");
@ -153,7 +153,11 @@ Notifications.sendsms = async (data, tribeId) => {
}; };
} }
let confsms = conf.sms; let confsms = conf.sms;
if (fs.existsSync(`../adminapi/objects/tribes/itm/${req.session.header.xtribe}.json`)) { if (
fs.existsSync(
`../adminapi/objects/tribes/itm/${req.session.header.xtribe}.json`
)
) {
const conftrib = fs.readJSONSync( const conftrib = fs.readJSONSync(
`../adminapi/objects/tribes/itm/${req.session.header.xtribe}.json` `../adminapi/objects/tribes/itm/${req.session.header.xtribe}.json`
); );
@ -206,14 +210,32 @@ Notifications.sendsms = async (data, tribeId) => {
*/ */
}; };
Notifications.manageemail = (data, template, tribe) => { Notifications.manageemail = async (data, templatename, tribe, lg,numberpersecond) => {
const sleep = (ms) => {
return new Promise((resolve) => setTimeout(resolve, ms));
};
/** /**
* Manage email publipostage * Manage email publipostage
* data must contain emailsto * data must contain
* data optionaly can contain Cc,Bcc as array of emails and attachments as array of filename (into the server) * {
* Await the 1st email * from:"", //mandatory
* cc:[],bcc:[], present in all email sent
* emailsto:[ //mandatory
* {
* to, //mandatory
* cc,bcc,
* attachements:[{filename:"text.txt",pathfile:"/media/phil/textA.txt","contenttype":"text/plain"}],
* any properties to template
* }
* ]
* }
* emailsto contain the personnalisation data in data we can have directly cc bcc, that is added to the main
*
* template a name that exist in /tribe/{{templatename}}_{{lg}}.js
*
*/ */
//console.log(data) //console.log(data)
const start = Date.now();
if (!data.emailsto || data.emailsto.length == 0) { if (!data.emailsto || data.emailsto.length == 0) {
return { return {
status: 406, status: 406,
@ -223,48 +245,72 @@ Notifications.manageemail = (data, template, tribe) => {
}; };
} }
if (typeof data.emailsto === "string") data.emailsto = [data.emailsto]; if (typeof data.emailsto === "string") data.emailsto = [data.emailsto];
const tplpath = `../${tribe}/template/${templatename}_${lg}.js`;
if (!fs.existsSync(path.resolve(template))){ if (!fs.existsSync(tplpath)) {
return { return {
status: 404, status: 404,
ref: "Notification", ref: "Notification",
msg: "templatenotfound", msg: "templatenotfound",
data: { template:path.resolve(template) }, data: { template: tplpath },
};
}
const results = { fail: [], success: [] };
const emailtosend = {};
// init with common propertie
Object.keys(data).forEach((k) => {
if (!["emailsto"].includes(k)) emailtosend[k] = data[k];
});
const tplemail = require(path.resolve(tplpath));
let sendit = { status: 200, ref: "Notifications", msg: "successfullsend" };
for (let i = 0; i < data.emailsto.length; i++) {
const email = data.emailsto[i];
emailtosend.to = email.to.toLowerCase().trim();
if (!Checkjson.testformat(emailtosend.to, "email")) {
results.fail.push({ to: emailtosend.to, err: ["errorformat"] });
} else {
emailtosend.subject = Mustache.render(tplemail.subject, email);
emailtosend.html = Mustache.render(tplemail.html, email);
emailtosend.text = Mustache.render(tplemail.text, email);
if (email.cc) {
emailtosend.cc += emailtosend.cc && emailtosend.cc != "" ? "," : "";
emailtosend.cc += email.cc.join(",");
}
if (email.bcc) {
emailtosend.bcc += emailtosend.bcc && emailtosend.bcc != "" ? "," : "";
emailtosend.bcc += email.bcc.join(",");
}
if (email.attachments) {
email.attachments.forEach((a) => tplemail.attachments.push(a));
}
//console.log(emailtosend)
sendit = await Notifications.sendmail(emailtosend, tribe);
//const sendit={status:200}
if (sendit.status == 200) {
results.success.push(emailtosend.to);
} else {
results.fail.push({ tp: emailtosend.to, status: sendit.status });
}
if ((i + 1) % numberpersecond === 0) {
console.log("Prochain lot attend 1 seconde");
await sleep(1000);
}
} }
} }
const tplemail = require(path.resolve(template)); fs.outputJSONSync(
let sendit={status:200,ref:"Notifications",msg:"successfullsend"}; `../${tribe}/logs/campains/${templatename}_${lg}_${Date.now()}`,
data.emailsto.forEach(async (e, i) => { results
if (Checkjson.testformat(e, "email")) { );
const dat = {}; return {
dat.to = e; status: 200,
dat.subject = Mustache.render(tplemail.subject, data); ref: "Wwws",
dat.html = Mustache.render(tplemail.html, data); msg: "campainsent",
dat.text = Mustache.render(tplemail.text, data); data: {
dat.Cc=tplemail.Cc emailsucces: results.success.length,
dat.Bcc=tplemail.Bcc emailfail: results.fail.length,
/* @TODO issue with data.Cc need to test timems: Date.now() - start,
if (data.Cc){ },
dat.Cc+=","+data.Cc.join(',') };
}
if (data.Bcc){
dat.Bcc+=","+data.Bcc.join(',')
}
*/
if (data.attachments){
data.attachments.forEach(a=>tplemail.attachments.push(a))
}
if (i == 0) {
sendit = await Notifications.sendmail(dat, tribe);
if (sendit.status != 200) return {status:406,ref:"Notifications",msg:"emailnotsent"};
} else {
Notifications.sendmail(dat, tribe);
}
} else {
// not a well formated email @todo add a log file to follow it
}
});
return sendit;
}; };
Notifications.sendmail = async (data, tribe) => { Notifications.sendmail = async (data, tribe) => {
@ -314,9 +360,11 @@ Notifications.sendmail = async (data, tribe) => {
data: { tribe: tribe }, data: { tribe: tribe },
}; };
} }
if (!data.from) { if (!data.from) {
data.from = conf.emailcontact; data.from = conf.emailcontact;
} }
let missingk = []; let missingk = [];
["from", "to", "subject", "html", "text"].forEach((k) => { ["from", "to", "subject", "html", "text"].forEach((k) => {
if (!data[k]) { if (!data[k]) {
@ -335,7 +383,7 @@ Notifications.sendmail = async (data, tribe) => {
const conftribfile = `../adminapi/objects/tribes/itm/${tribe}.json`; const conftribfile = `../adminapi/objects/tribes/itm/${tribe}.json`;
if (fs.existsSync(conftribfile)) { if (fs.existsSync(conftribfile)) {
const conftrib = fs.readJSONSync(conftribfile); const conftrib = fs.readJSONSync(conftribfile);
if (!conftrib.emailcontact){ if (!conftrib.emailcontact) {
return { return {
status: 428, status: 428,
ref: "Notifications", ref: "Notifications",
@ -344,9 +392,10 @@ Notifications.sendmail = async (data, tribe) => {
}; };
} }
confsmtp = conftrib.smtp; confsmtp = conftrib.smtp;
if (!data.from || data.from == conf.emailcontact) data.from = conftrib.emailcontact; if (!data.from || data.from == conf.emailcontact)
data.from = conftrib.emailcontact;
} }
// console.log(confsmtp) //console.log(confsmtp);
const transporter = await nodemailer.createTransport(confsmtp); const transporter = await nodemailer.createTransport(confsmtp);
if (data.filelist) { if (data.filelist) {
data.attachments = []; data.attachments = [];
@ -368,14 +417,36 @@ Notifications.sendmail = async (data, tribe) => {
//console.log("data:", data); //console.log("data:", data);
let res; let res;
let error; let error;
try{ /*console.log(
res = await transporter.sendMail(data); "from:",
}catch(err){ data.from,
console.log(err) " to:",
error=err data.to,
" replyto:",
data.replyto,
" cc:",
data.cc,
" bcc:",
data.bcc,
" subject:",
data.subject
);
*/
//fs.outputFile(`../${tribe}/template/test.html`, data.html);
try {
res = await transporter.sendMail(data);
} catch (err) {
console.log("Erreur :", err);
if (err.code) {
error = err.code;
} else {
error = err;
}
} }
if ( if (
res && res.accepted && res &&
res.accepted &&
data.to.split(",").reduce((acc, m) => acc && res.accepted.includes(m), true) data.to.split(",").reduce((acc, m) => acc && res.accepted.includes(m), true)
) { ) {
data.accepted = res.accepted; data.accepted = res.accepted;
@ -386,7 +457,7 @@ Notifications.sendmail = async (data, tribe) => {
msg: "successfullsentemail", msg: "successfullsentemail",
data, data,
}; };
} else if ( res && res.accepted && res.rejected) { } else if (res && res.accepted && res.rejected) {
data.accepted = res.accepted; data.accepted = res.accepted;
data.rejected = res.rejected; data.rejected = res.rejected;
return { status: 410, ref: "Notifications", msg: "errsendmail", data }; return { status: 410, ref: "Notifications", msg: "errsendmail", data };

View File

@ -11,8 +11,73 @@ const sharp = require("sharp");
const readlineSync = require("readline-sync"); const readlineSync = require("readline-sync");
const Odmdb = require("./Odmdb.js"); const Odmdb = require("./Odmdb.js");
const conf = require(`../../../adminapi/objects/tribes/itm/adminapi.json`); const conf = require(`../../../adminapi/objects/tribes/itm/adminapi.json`);
const currentmod = "Wwws";
const log = conf.api.activelog.includes(currentmod);
const Wwws = {}; const Wwws = {};
Wwws.getwco = (wconame, ctx) => {
const filereq = `../${ctx.wcotribe}/objects/wco/${wconame}/${wconame}.js`;
const wcoconf = `../${ctx.wcotribe}/objects/wco/itm/${wconame}.json`;
if (!fs.existsSync(filereq) || !fs.existsSync(wcoconf)) {
return {
status: 404,
ref: "Wwws",
msg: "filedoesnotexist",
data: { js: filereq, wcoconf: wcoconf },
};
}
//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
const webconf = `../${ctx.tribe}/objects/wwws/itm/${ctx.xapp}.json`;
const wcoinfo = fs.readJSONSync(wcoconf);
const webpage = fs.readJSONSync(webconf);
if (wcoinfo.tpl && Object.keys(wcoinfo.tpl).length > 0) {
Object.keys(wcoinfo.tpl).forEach((t) => {
if (!Object.keys(webpage.pages[ctx.pagename].tpl).includes(t)) {
webpage.pages[ctx.pagename].tpl[t] = wcoinfo.tpl[t];
}
});
}
if (wcoinfo.tpldatamodel && Object.keys(wcoinfo.tpldatamodel).length > 0) {
Object.keys(wcoinfo.tpldatamodel).forEach((t) => {
const pathtpldata = `../${ctx.tribe}/objects/wwws/${ctx.xapp}/src/tpldata/${wconame}/${t}`;
if (!Object.keys(webpage.pages[ctx.pagename].tpldata).includes(t)) {
webpage.pages[ctx.pagename].tpldata[t] = pathtpldata;
}
wcoinfo.lang.forEach((l) => {
if (!fs.existsSync(`${pathtpldata}_${l}.json`)) {
if (!fs.existsSync(`../${wcoinfo.tpldatamodel[t]}_${l}.json`)) {
fs.copySync(
`../${wcoinfo.tpldatamodel[t]}_${l}.json`,
`${pathtpldata}_${l}.json`
);
}
}
});
});
}
if (wcoinfo.ref && Object.keys(wcoinfo.ref).length > 0) {
Object.keys(wcoinfo.ref).forEach((t) => {
t=t.replace("{{tribe}}",ctx.tribe)
if (!Object.keys(webpage.pages[ctx.pagename].ref).includes(t)) {
webpage.pages[ctx.pagename].ref[t] = wcoinfo.ref[t];
}
});
}
if (wcoinfo.schema && wcoinfo.schema.length > 0)
[
wcoinfo.schema.forEach((s) => {
s = s.replace("{{tribe}}", ctx.tribe);
if (webpage.pages[ctx.pagename].schema.includes(s)) {
webpage.pages[ctx.pagename].schema.pusf(s);
}
}),
];
fs.outputJSONSync(webconf,webpage)
return { status: 200, ref:"Wwws",msg:"wcoupdatesuccessinpageconf",data: { file: path.resolve(filereq) } };
};
Wwws.build = (tribeId, webapp, srcdist, options) => { Wwws.build = (tribeId, webapp, srcdist, options) => {
console.log(`Building ${tribeId}/objects/wwws/${webapp}/${srcdist}`); console.log(`Building ${tribeId}/objects/wwws/${webapp}/${srcdist}`);
const pathto = `../${tribeId}/objects/wwws`; const pathto = `../${tribeId}/objects/wwws`;
@ -22,8 +87,9 @@ Wwws.build = (tribeId, webapp, srcdist, options) => {
} else { } else {
confwww = { confwww = {
website: webapp, website: webapp,
appimgs:[], appimgs: [],
commentappimg:"Image list in src that are used by app that must be copy into /dist", commentappimg:
"Image list in src that are used by app that must be copy into /dist",
apxtri: { apxtri: {
headers: { headers: {
xtrkversion: 1, xtrkversion: 1,
@ -60,18 +126,18 @@ Wwws.build = (tribeId, webapp, srcdist, options) => {
tpl: {}, tpl: {},
tpldata: {}, tpldata: {},
itms: {}, itms: {},
ref: { ref: {},
Checkjson: "adminapi/objects/tplstrings/Checkjson", schema: [],
Notification: "adminapi/objects/tplstrings/Notifications", options: {},
Odmdb: "adminapi/objects/tplstrings/Odmdb",
Pagans: "adminapi/objects/tplstrings/Pagans",
Middlewares: "adminapi/objects/tplstrings/middlewares",
},
schema: ["adminapi/objects/pagans", `${tribeId}/objects/persons`],
options: { profil: `${tribeId}/objects/options/profil` },
wcodata: {}, wcodata: {},
appdata: {}, appdata: {},
}; }; // test if lib exist or not if not create a symlink with node_modules
/*if (
(src.includes("static/lib/") || src.includes("wco/")) &&
!fs.existsSync(`${pathto}/${webapp}/src/${src}`)
) {
Wwws.getsymlink(`${pathto}/${webapp}/src/${src}`, tribe);
}*/
} }
if (!confwww.pages[pgname].languages.includes(lg)) if (!confwww.pages[pgname].languages.includes(lg))
confwww.pages[pgname].languages.push(lg); confwww.pages[pgname].languages.push(lg);
@ -81,7 +147,10 @@ Wwws.build = (tribeId, webapp, srcdist, options) => {
const dc = pg.window.document; const dc = pg.window.document;
let pgscripts = []; let pgscripts = [];
dc.querySelectorAll("script[src]").forEach((s) => { dc.querySelectorAll("script[src]").forEach((s) => {
if (!pgscripts.includes(s.getAttribute("src"))) { if (
/\/api\/.*\/wwws\/objects\/wco\/itm\/.*/.test(s.src) &&
!pgscripts.includes(s.src)
) {
pgscripts.push(s.getAttribute("src")); pgscripts.push(s.getAttribute("src"));
} }
}); });
@ -92,9 +161,9 @@ Wwws.build = (tribeId, webapp, srcdist, options) => {
imgsrc.replace(/(.*)\.(png|png|gif|bmp|jpg|jpeg)$/, "$1.webp") imgsrc.replace(/(.*)\.(png|png|gif|bmp|jpg|jpeg)$/, "$1.webp")
); );
if (!appimgs[imgsrc]) { if (!appimgs[imgsrc]) {
appimgs[imgsrc]={pages:[]}; appimgs[imgsrc] = { pages: [] };
} }
appimgs[imgsrc].pages.push(pginfo) appimgs[imgsrc].pages.push(pginfo);
}); });
let wcojs = ""; let wcojs = "";
pgscripts.forEach((s) => { pgscripts.forEach((s) => {
@ -129,7 +198,7 @@ Wwws.build = (tribeId, webapp, srcdist, options) => {
.sync(`${pathto}/${webapp}/src/tpldata/${pgname}/*.json`) .sync(`${pathto}/${webapp}/src/tpldata/${pgname}/*.json`)
.forEach((t) => { .forEach((t) => {
const tpldataname = path.parse(t).name.replace(/_..$/, ""); const tpldataname = path.parse(t).name.replace(/_..$/, "");
console.log("tpldata:",tpldataname); console.log("tpldata:", tpldataname);
confwww.pages[pgname].tpldata[tpldataname] = `${tribeId}/${t.replace( confwww.pages[pgname].tpldata[tpldataname] = `${tribeId}/${t.replace(
/_..\.json$/, /_..\.json$/,
"" ""
@ -172,30 +241,32 @@ Wwws.build = (tribeId, webapp, srcdist, options) => {
); );
} }
}); });
console.log(appimgs) //console.log(appimgs)
const commonfilestrt = {}; const commonfilestrt = {};
// force some image to be in dist that are not existing in html mainly used by wco app // force some image to be in dist that are not existing in html mainly used by wco app
confwww.commonfiles.forEach(i=>{ confwww.commonfiles.forEach((i) => {
const src = `${pathto}/${webapp}/src/${i}`; const src = `${pathto}/${webapp}/src/${i}`;
const dist = `${pathto}/${webapp}/dist/${i}`; const dist = `${pathto}/${webapp}/dist/${i}`;
//console.log(imgsrc,"---------------",imgdist) //console.log(imgsrc,"---------------",imgdist)
if (!fs.existsSync(src)){ if (!fs.existsSync(src)) {
commonfilestrt[src]={ERROR:`this file does not exist request by wwws/itm/${webapp}.json`} commonfilestrt[src] = {
ERROR: `this file does not exist request by wwws/itm/${webapp}.json`,
};
} else if (!fs.existsSync(dist)) { } else if (!fs.existsSync(dist)) {
fs.ensureDirSync(path.dirname(dist)) fs.ensureDirSync(path.dirname(dist));
fs.copyFileSync(src,dist) fs.copyFileSync(src, dist);
} }
}) });
const imgtrt={} const imgtrt = {};
Object.keys(appimgs).forEach(async (i) => { Object.keys(appimgs).forEach(async (i) => {
const imgsrc = `${pathto}/${webapp}/src/${i}`; const imgsrc = `${pathto}/${webapp}/src/${i}`;
const imgdist = `${pathto}/${webapp}/dist/${i.replace( const imgdist = `${pathto}/${webapp}/dist/${i.replace(
/(.*)\.(png|png|gif|bmp|jpg|jpeg)$/i, /(.*)\.(png|png|gif|bmp|jpg|jpeg)$/i,
"$1.webp" "$1.webp"
)}`; )}`;
console.log("imgsrc:",imgsrc," imgdist:",imgdist) console.log("imgsrc:", imgsrc, " imgdist:", imgdist);
if (fs.existsSync(imgsrc)) { if (fs.existsSync(imgsrc)) {
const srcstats = fs.statfsSync(imgsrc); const srcstats = fs.statfsSync(imgsrc);
let newimg = sharp(imgsrc); let newimg = sharp(imgsrc);
@ -208,7 +279,7 @@ Wwws.build = (tribeId, webapp, srcdist, options) => {
) { ) {
newimg = newimg.resize({ width: 1920, height: 1080, fit: "inside" }); newimg = newimg.resize({ width: 1920, height: 1080, fit: "inside" });
} }
fs.ensureDirSync(path.dirname(imgdist)) fs.ensureDirSync(path.dirname(imgdist));
await newimg.webp({ quality: 80 }).toFile(imgdist); await newimg.webp({ quality: 80 }).toFile(imgdist);
} }
const diststats = fs.statfsSync(imgdist); const diststats = fs.statfsSync(imgdist);
@ -227,7 +298,12 @@ Wwws.build = (tribeId, webapp, srcdist, options) => {
// saved new conf for updatelocaldb data // saved new conf for updatelocaldb data
fs.outputJSONSync(`${pathto}/itm/${webapp}.json`, confwww, { spaces: 2 }); fs.outputJSONSync(`${pathto}/itm/${webapp}.json`, confwww, { spaces: 2 });
console.log(imgtrt); console.log(imgtrt);
return { status: 200, ref: "Wwws", msg: "success", data: { imgtrt,commonfilestrt } }; return {
status: 200,
ref: "Wwws",
msg: "success",
data: { imgtrt, commonfilestrt },
};
}; };
if (process.argv && process.argv.length == 5) { if (process.argv && process.argv.length == 5) {
@ -306,7 +382,7 @@ Wwws.initlocaldata = (tribe, appname, pagename, version, profils, lg) => {
tpl: {}, tpl: {},
tpldata: {}, tpldata: {},
ref: {}, ref: {},
schema: [], schema: {},
}; };
localstorage.headers.xlang = lg; localstorage.headers.xlang = lg;
// A faire plus tard charger tous les referentiele et les data pour une page adminpage // A faire plus tard charger tous les referentiele et les data pour une page adminpage
@ -469,7 +545,7 @@ Wwws.initlocaldata = (tribe, appname, pagename, version, profils, lg) => {
"/etc/nginx/proxy_params", "/etc/nginx/proxy_params",
mustache.render(proxyparams, paramconf), mustache.render(proxyparams, paramconf),
"utf8" "utf8"
); );ln -s ../../../../../../../adminapi/node_modules/axios axios
if (!fs.existsSync(paramconf.nginx.logs)) fs.mkdirSync(paramconf.nginx.logs); if (!fs.existsSync(paramconf.nginx.logs)) fs.mkdirSync(paramconf.nginx.logs);
paramconf.nginx.firstinstall = true; paramconf.nginx.firstinstall = true;
fs.outputJsonSync("../tribes/conf.json", paramconf, { fs.outputJsonSync("../tribes/conf.json", paramconf, {
@ -483,6 +559,18 @@ Wwws.create = (paramnginx) => {
/** /**
* Create an nginx conf to make available a spaceweb for a tribe /www/appname/ * Create an nginx conf to make available a spaceweb for a tribe /www/appname/
* *
* create
* /dist
* /src/static/lib/
* ln -s ../../../../../../../adminapi/node_modules/axios axios
*
*
*
*
*
*
*
*
*/ */
const res = { const res = {
status: 200, status: 200,

View File

@ -28,29 +28,42 @@ router.post(
); );
/** /**
* @api {put} /adminapi/wwws/webcomponents - Get local web components * @api {get} /adminapi/wwws/getwco/:wconame - Add a wco for an app
* @apiGroup Wwws * @apiGroup Wwws
* @apiName getwco * @apiName getwco
* @apiDescription Get web component from backend to localstorage for development. This is anonymous but must be authenticated with accessright to other tribe to get their web component.<br> For production it will generate a unique id that store to add in updatelocaldb with in production space /js/uniqueid.js css/uniqueid.css pagename.html with link in it * @apiDescription Get the wco name.js that make the wco work. It checks that the wcotribe allow the couple tribe (that request) and code exist data base from backend to localstorage for anonymous (see Get app data model)
* *
* @apiBody {object} tribelistwco { wco:{tribe:[wconame]}, mode:"dev"|"prod"} * @apiParam {string} name unique wco name
*/ * @apiQuery {string} tribe that request access to
router.put( * @apiQuery {string} wcotribe where the wco is stored
"/updatelocalwcoanonymous", * @apiQuery {string} xapp for which website is requested
checkHeaders, * @apiQuery {string} pagename for which page name we need to add in localdb
(req, res) => { * @apiQuery {string} code a code for tribe
console.log("localstorage anonymous for web component", req.session.header.xalias); *
req.session.header.xprofils = ["anonymous"]; *
console.log(req.session.header.xprofils); * http://admin.adminapi.newdev.ants/api/adminapi/wwws/getwco/apx.js?wcotribe=adminapi&tribe=adminapi&xapp=admin&pagename=admindata&code=enjoy
//ajouter une detection de changement */
const getlocal = Wwws.initlocalwco( router.get("/getwco/:wconame", (req, res) => {
req.body, console.log(req.params);
req.session.header.xprofils, console.log(req.query);
req.session.header.xlang const mandatoryquery= ["wcotribe","tribe","xapp","pagename","code"]
); let missquery=""
res.status(getlocal.status).json(getlocal); mandatoryquery.forEach(q=>{
if (!req.query[q] || req.query[q]=="") {
missquery+=q+" "
}
})
if (missquery!=""){
res.status(403).json({status:403,ref:"Wwws",msg:"missquery",data:{missquery}})
}else{
const getwco=Wwws.getwco(req.params.wconame.replace(/\.js$/,''),req.query)
if (getwco.status==200){
res.sendFile(getwco.data.file)
}else{
res.status(getwco.status).json(getwco);
}
} }
); });
/** /**
* @api {get} /adminapi/wwws/updatelocaldbanonymous/:tribe/:appname/:pagename/:version - Get localdb for app anonymous only * @api {get} /adminapi/wwws/updatelocaldbanonymous/:tribe/:appname/:pagename/:version - Get localdb for app anonymous only
@ -58,11 +71,11 @@ router.put(
* @apiName getappcontextforanonymous * @apiName getappcontextforanonymous
* @apiDescription Get data base from backend to localstorage for anonymous (see Get app data model) * @apiDescription Get data base from backend to localstorage for anonymous (see Get app data model)
* *
* @apiParams {string} tribe (adminapi,smatchit,..) to looking for * @apiParam {string} tribe (adminapi,smatchit,..) to looking for
* @apiParams {string} appname agregate a full data referential to store localy * @apiParam {string} appname agregate a full data referential to store localy
* @apiParams {string} pagename app page name * @apiParam {string} pagename app page name
* @apiParams {interger} version the current version * @apiParam {interger} version the current version
*/ */
router.get( router.get(
"/updatelocaldbanonymous/:tribe/:appname/:pagename/:version", "/updatelocaldbanonymous/:tribe/:appname/:pagename/:version",
checkHeaders, checkHeaders,
@ -89,10 +102,10 @@ router.get(
* @apiName getappcontext * @apiName getappcontext
* @apiDescription Get data base from backend to localstorage for authenticated user * @apiDescription Get data base from backend to localstorage for authenticated user
* *
* @apiParams {string} tribe (adminapi,smatchit,..) to looking for * @apiParam {string} tribe (adminapi,smatchit,..) to looking for
* @apiParams {string} appname agregate a full data referential to store localy * @apiParam {string} appname agregate a full data referential to store localy
* @apiParams {string} pagename app page name * @apiParam {string} pagename app page name
* @apiParams {interger} version the current version * @apiParam {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 * @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} datamodelupdate * @apiSuccessExample {json} datamodelupdate
* {"status":200, "ref":"Wwws", "msg":"datamodelupdate", "data":{version,confpage,profils,schema,options,ref,tpl,tpldata}} * {"status":200, "ref":"Wwws", "msg":"datamodelupdate", "data":{version,confpage,profils,schema,options,ref,tpl,tpldata}}
@ -106,7 +119,8 @@ router.get(
*/ */
router.get( router.get(
"/updatelocaldb/:tribe/:appname/:pagename/:version", "/updatelocaldb/:tribe/:appname/:pagename/:version",
checkHeaders, isAuthenticated, checkHeaders,
isAuthenticated,
(req, res) => { (req, res) => {
console.log("pass localstorage", req.session.header.xalias); console.log("pass localstorage", req.session.header.xalias);
console.log(req.session.header.xprofils); console.log(req.session.header.xprofils);
@ -128,8 +142,8 @@ router.get(
* @apiName createPagename * @apiName createPagename
* @apiDescription Create a pagename from /appscreen/template/:pagename with * @apiDescription Create a pagename from /appscreen/template/:pagename with
* *
* @apiParams {string} tribe (adminapi,smatchit,..) to looking for * @apiParam {string} tribe (adminapi,smatchit,..) to looking for
* @apiParams {string} appname agregate a full data referential to store localy * @apiParam {string} appname agregate a full data referential to store localy
* @apiSuccess {object} contain cuurent version of the data model * @apiSuccess {object} contain cuurent version of the data model
* @apiSuccessExample {json} Success-Response: * @apiSuccessExample {json} Success-Response:
* HTTP/1.1 200 OK * HTTP/1.1 200 OK
@ -143,14 +157,12 @@ router.get("/buildpage/:tribe/:appname/:pagename", checkHeaders, (req, res) => {
.status(404) .status(404)
.json({ status: 404, ref: "Wwws", msg: "localdbnotfound", data: {} }); .json({ status: 404, ref: "Wwws", msg: "localdbnotfound", data: {} });
} }
res res.status(200).json({
.status(200) status: 200,
.json({ ref: "Wwws",
status: 200, msg: "lastversion",
ref: "Wwws", data: { version: fs.readJSONSync(localdbf).version },
msg: "lastversion", });
data: { version: fs.readJSONSync(localdbf).version },
});
}); });
module.exports = router; module.exports = router;

View File

@ -23,6 +23,9 @@ location ~* /trk/ {
location /adminapi/Checkjson.js { location /adminapi/Checkjson.js {
alias {{{townpath}}}/adminapi/apxtri/models/Checkjson.js; alias {{{townpath}}}/adminapi/apxtri/models/Checkjson.js;
} }
location ~ ^/(?<folder>[^/]+)/node_modules/(?<file>.+)$ {
alias {{{townpath}}}/$folder/node_modules/$file;
}
location /setup.sh { location /setup.sh {
alias {{{townpath}}}/adminapi/apxtri/setup/setup.sh; alias {{{townpath}}}/adminapi/apxtri/setup/setup.sh;
} }

71
schema/wco.json Normal file
View File

@ -0,0 +1,71 @@
{
"$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",
"type": "object",
"properties": {
"wconame": {
"description": "Folder name into a tribeId/objects/wco/itm",
"title": "Web component reusable in web project based with tailwindcss",
"type": "string"
},
"owner": {
"description": "owner that earn some fees",
"type": "string"
},
"codehash": {
"description": "Code signature of alias publickey",
"type": "string"
},
"thumbnail":{
"title":"Thumbnail of the component",
"type":"string"
},
"title":{
"title":"Short description of the wco",
"type":"string"
},
"description":{
"title":"Long description in html of the component",
"type":"string"
},
"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"
},
"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"
}
},
"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": []
}
}
}

View File

@ -1,6 +1,6 @@
{ {
"$schema": "https://json-schema.org/draft/2020-12/schema", "$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "nationchains/schema/www", "$id": "adminapi/schema/wwws",
"title": "www", "title": "www",
"description": "A space web available for a domaine, with accessright", "description": "A space web available for a domaine, with accessright",
"type": "object", "type": "object",