757 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			757 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| var apx = apx || {};
 | |
| apx.apxauth = {};
 | |
| apx.apxauth.loadwco = async (id, ctx) => {
 | |
|   // check if not authenticate, do nothing cause by default screensignin and wait authentification
 | |
|   //       if     authenticate, if url xhash then redirect if no url then change wco-link=screenmyworld
 | |
|   // if (dayjs(apx.data.headers.xdays).diff(dayjs(), "hours") >= 24) apx.apxauth.checkisauth();
 | |
|   //load main.mustache of the component
 | |
|   //when wco-xxx change it run this function
 | |
|   console.log(
 | |
|     `Load wconame:apxauth apx.apxauth.loadwco with id:${id} and ctx: ${JSON.stringify(
 | |
|       ctx
 | |
|     )}`
 | |
|   );
 | |
|   // Check that in localdb tpl exist if not means it is not authenticated 
 | |
|   if (!apx.data.tpl[`apxauthscreen${ctx.link}`]) ctx.link="signin";
 | |
|   const tpldataname = `${apx.data.pagename}_${id}_apxauth`;
 | |
|   const apxauthid = document.getElementById(id);
 | |
|   const data = apx.apxauth.getdata(id, ctx);
 | |
|   if (apxauthid.innerHTML.trim() === "") {
 | |
|     apxauthid.innerHTML = Mustache.render(apx.data.tpl.apxauthmain, data);
 | |
|   }
 | |
|   apxauthid.querySelector(`.screenaction`).innerHTML = Mustache.render(
 | |
|     apx.data.tpl[`apxauthscreen${ctx.link}`],
 | |
|     data
 | |
|   );
 | |
|   apxauthid.querySelector(`.msginfo`).innerHTML = "";
 | |
| };
 | |
| 
 | |
| apx.apxauth.getdata = (id, ctx) => {
 | |
|   const tpldataname = `${apx.data.pagename}_${id}_apxauth`;
 | |
|   const data = JSON.parse(JSON.stringify(apx.data.tpldata[tpldataname]));
 | |
|   data.id = id;
 | |
|   data.xalias = apx.data.headers.xalias;
 | |
|   data.xtribe = apx.data.headers.xtribe;
 | |
| 
 | |
|   data.emailsupport = apx.data?.appdata?.emailsupport
 | |
|     ? apx.data.appdata.emailsupport
 | |
|     : "";
 | |
|   console.log("data:",data)
 | |
|   switch (ctx.link) {
 | |
|     case "myworld":
 | |
|       if (!data.profils) data.profils = [];
 | |
|       apx.data.headers.xprofils.forEach((p) => {
 | |
|         if (!["anonymous", "pagans", "persons"].includes(p)) {
 | |
|           data.profils.push(apx.data.options.profil.itms[p].title);
 | |
|         }
 | |
|       });
 | |
|       data.noprofils = data.profils.length == 0;
 | |
|       data.member = apx.data.headers.xprofils.includes("persons");
 | |
|       data.websites = apx.data?.appdata?.websites || [];
 | |
|       data.optionlinks=apx.data.tpldata[tpldataname].optionlinks
 | |
|       data.town=apx.data.town
 | |
|       data.nation=apx.data.nation
 | |
|       if (1==1 || apx.data.headers.xprofils.includes('major')){
 | |
|          apx.data.tpldata[tpldataname].optionlinksmajor.forEach(o=>data.optionlinks.push(o))
 | |
|          apx.save()
 | |
|       }
 | |
|       if (!apx.data.itms) apx.data.itms={}
 | |
|       if (!apx.data.wco) apx.data.wco={} 
 | |
| 
 | |
|       // get towns list
 | |
|       axios
 | |
|         .get(`/api/apxtri/odmdb/idx/apxtri/towns/towns`, {
 | |
|           headers: apx.data.headers, withCredentials:true
 | |
|         })
 | |
|         .then((rep) => {
 | |
|           console.log(rep)
 | |
|           if (rep.status==200){
 | |
|             apx.data.itms.towns=rep.data.data.idx
 | |
|             data.townsnumber= Object.keys(apx.data.itms.towns).length;
 | |
|             apx.data.wco.townsnumber={textContent:Object.keys(apx.data.itms.towns).length};
 | |
|             apx.listendatawco('townsnumber');
 | |
|             apx.save()
 | |
|           }
 | |
|         })
 | |
|         .catch((err) => {
 | |
|           console.log("ERROR, geting towns itms not available",err)
 | |
|         });
 | |
|       axios
 | |
|         .get(`/api/apxtri/odmdb/idx/apxtri/pagans/lst_alias`, {
 | |
|           headers: apx.data.headers, withCredentials:true
 | |
|         })
 | |
|         .then((rep) => {
 | |
|           if (rep.status==200){
 | |
|             console.log(rep)
 | |
|             data.pagansnumber=rep.data.data.idx.length
 | |
|             apx.data.wco.pagansnumber={textContent:rep.data.data.idx.length};
 | |
|             apx.listendatawco('pagansnumber');
 | |
|             apx.save();
 | |
|           }
 | |
|         })
 | |
|         .catch((err) => {
 | |
|           console.log("ERROR, geting pagans itms not available",err)
 | |
|         });
 | |
|       break;
 | |
|     case "information":
 | |
|       break;
 | |
|     default:
 | |
|       break;
 | |
|   }
 | |
|   console.log("data for tpl:", data);
 | |
|   return data;
 | |
| };
 | |
| 
 | |
| apx.apxauth.redirecturlwithauth = (
 | |
|   url,
 | |
|   tribe,
 | |
|   webapp,
 | |
|   newwindow,
 | |
|   windowname = "_blank"
 | |
| ) => {
 | |
|   url = url.replace(/_[a-zA-Z0-9]{2}\.html/, `_${apx.data.headers.xlang}.html`);
 | |
|   url += `?xtribe=${tribe}&xapp=${webapp}&xalias=${apx.data.headers.xalias}`;
 | |
|   url += `&xdays=${apx.data.headers.xdays}&xhash=${apx.data.headers.xhash}`;
 | |
|   url += `&xprofils=${apx.data.headers.xprofils.join(",")}`;
 | |
|   url += `&xtrkversion=${apx.data.headers.xtrkversion}&xuuid=${apx.data.headers.xuuid}`;
 | |
|   if (newwindow) {
 | |
|     try {
 | |
|       const newwin = window.open(url, windowname);
 | |
|       if (newwin === null || typeof newwin === "undefined") {
 | |
|         console.warn(
 | |
|           "L'ouverture de la fenêtre a été bloquée par un bloqueur de pop-up."
 | |
|         );
 | |
|         // Vous pouvez informer l'utilisateur ici qu'il doit désactiver son bloqueur de pop-up
 | |
|         alert(
 | |
|           "Votre navigateur a bloqué l'ouverture d'un nouvel onglet. Veuillez autoriser les pop-ups pour ce site."
 | |
|         );
 | |
|       } else {
 | |
|         // Optionnel: Mettre le focus sur la nouvelle fenêtre/onglet
 | |
|         newwin.focus();
 | |
|       }
 | |
|       return newwin;
 | |
|     } catch (error) {
 | |
|       console.error(
 | |
|         "Une erreur est survenue lors de l'ouverture de l'onglet :",
 | |
|         error
 | |
|       );
 | |
|       return null;
 | |
|     }
 | |
|   }
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * logout
 | |
|  * Clean any private key into memory of this app and in the backend
 | |
|  */
 | |
| apx.apxauth.logout = () => {
 | |
|   axios
 | |
|     .get(`/api/apxtri/pagans/logout`, {
 | |
|       headers: apx.data.headers, withCredentials:true
 | |
|     })
 | |
|     .then((rep) => {
 | |
|       console.log("logout", rep);
 | |
|     })
 | |
|     .catch((err) => {
 | |
|       console.log("Erreur logout check:", err);
 | |
|     });
 | |
|   apx.data = apxtri;
 | |
|   apx.save();
 | |
|   if (apx.pagecontext.hash.url) {
 | |
|     window.location.href = apx.pagecontext.hash.url;
 | |
|   } else {
 | |
|     location.reload();
 | |
|   }
 | |
| };
 | |
| 
 | |
| apx.apxauth.setheadersauth = async (
 | |
|   alias,
 | |
|   passphrase,
 | |
|   publickey,
 | |
|   privatekey,
 | |
|   rememberme
 | |
| ) => {
 | |
|   /**
 | |
|    * Set header with relevant authentification data
 | |
|    * @return {status=200 if apx.data.headers and apx.data.auth properly set}
 | |
|    *         {status: 406 or 500 in case issue}
 | |
|    */
 | |
|   //console.log(alias, passphrase, publickey, privatekey);
 | |
|   if (
 | |
|     alias.length < 3 ||
 | |
|     publickey.length < 200 ||
 | |
|     (privatekey && privatekey.lengtht < 200)
 | |
|   ) {
 | |
|     return {
 | |
|       status: 406,
 | |
|       ref: "Pagans",
 | |
|       msg: "aliasorprivkeytooshort",
 | |
|       data: {},
 | |
|     };
 | |
|   }
 | |
|   if (!passphrase) passphrase = "";
 | |
|   if (rememberme) {
 | |
|     apx.data.auth = {
 | |
|       alias: alias,
 | |
|       publickey: publickey,
 | |
|       privatekey: privatekey,
 | |
|       passphrase: passphrase,
 | |
|     };
 | |
|   } else if (apx.data.auth) {
 | |
|     delete apx.data.auth;
 | |
|     apx.save();
 | |
|   }
 | |
|   apx.data.headers.xalias = alias;
 | |
|   apx.data.headers.xdays = dayjs().valueOf();
 | |
|   const msg = `${alias}_${apx.data.headers.xdays}`;
 | |
|  
 | |
|   try {
 | |
|     apx.data.headers.xhash = await apx.apxauth.clearmsgSignature(
 | |
|       publickey,
 | |
|       privatekey,
 | |
|       passphrase,
 | |
|       msg
 | |
|     );
 | |
|   } catch (err) {
 | |
|     return {
 | |
|       status: 500,
 | |
|       ref: "Middlewares",
 | |
|       msg: "unconsistentpgp",
 | |
|       data: { err: err },
 | |
|     };
 | |
|   }
 | |
|   apx.save();
 | |
|   console.log("xhash set with:", apx.data.headers.xhash);
 | |
|   return { status: 200 };
 | |
| };
 | |
| apx.apxauth.authentifyme = async (
 | |
|   id,
 | |
|   alias,
 | |
|   passphrase,
 | |
|   privatekey,
 | |
|   rememberme
 | |
| ) => {
 | |
|   /**
 | |
|    * Set apx.data.auth with pub, priv, passphrase alias that allow authentification
 | |
|    * set headers with xdays (timestamp) and xhash of message: {alias}_{timestamp} generate with pub & priv key
 | |
|    *
 | |
|    * @Param {key} publickeycreate  optional when alias does not exist
 | |
|    */
 | |
|   //console.log(alias, passphrase);
 | |
|   //console.log(privatekey);
 | |
|   //clean previous answer if exist
 | |
| 
 | |
|   const idparent = document
 | |
|     .getElementById(id)
 | |
|     .parentElement?.closest("[wco-name]")
 | |
|     .getAttribute("id");
 | |
|   document.querySelector(`#${id} .msginfo`).innerHTML = "";
 | |
|   if (alias.length < 3 || privatekey.length < 200) {
 | |
|     apx.notification(`#${id} .msginfo`, {
 | |
|       status: 500,
 | |
|       ref: "Pagans",
 | |
|       msg: "aliasorprivkeytooshort",
 | |
|       data: {},
 | |
|     });
 | |
|     return false;
 | |
|   }
 | |
|   console.log(`get /api/apxtri/pagans/alias/${alias}`);
 | |
|   axios
 | |
|     .get(`/api/apxtri/pagans/alias/${alias}`, {
 | |
|       headers: apx.data.headers, withCredentials:true
 | |
|     })
 | |
|     .then(async (rep) => {
 | |
|       //console.log(rep.data);
 | |
|       const setheaders = await apx.apxauth.setheadersauth(
 | |
|         alias,
 | |
|         passphrase,
 | |
|         rep.data.data.publickey,
 | |
|         privatekey,
 | |
|         rememberme
 | |
|       );
 | |
|       if (setheaders.status != 200) {
 | |
|         apx.notification(`#${id} .msginfo`, setheaders);
 | |
|       } else {
 | |
|         console.log("SetheadersOK");
 | |
|         console.log(`/api/apxtri/pagans/isauth`);
 | |
|         axios
 | |
|           .get(`/api/apxtri/pagans/isauth`, {
 | |
|             headers: apx.data.headers,
 | |
|             withCredentials: true,
 | |
|           })
 | |
|           .then((rep) => {
 | |
|             // Authenticate then store profils in header
 | |
|             // remove xhash for security this xhaskl is stored from the server as cookie http only.
 | |
|             apx.data.headers.xprofils = rep.data.data.xprofils;
 | |
|             delete apx.data.headers.xhash;
 | |
|             apx.save();
 | |
|             // if this page is call with apxid_fr.html?url=httpsxxx then it redirect to this page.
 | |
|             //alert(`${window.location.href.includes("/src/")?"/src/":""}${apx.pagecontext.hash.url}`)
 | |
|             if (apx.pagecontext.hash.url) {
 | |
|               window.location.href = `${apx.pagecontext.hash.url}`;
 | |
|             } else {
 | |
|               //location.reload();
 | |
|               document
 | |
|                 .getElementById(idparent)
 | |
|                 .setAttribute("wco-link", "myworld");
 | |
|             }
 | |
|           })
 | |
|           .catch((err) => {
 | |
|             console.log("Not authentify:", err);
 | |
|             delete apx.data.auth;
 | |
|             apx.save();
 | |
|             document
 | |
|               .getElementById(idparent)
 | |
|               .setAttribute("wco-link", "signin");
 | |
|             if (err.response) {
 | |
|               apx.notification(`#${id} .msginfo`, err.response.data);
 | |
|             } else if (err.request) {
 | |
|               apx.notification(`#${id} .msginfo`, {
 | |
|                 status: 500,
 | |
|                 ref: "Middlewares",
 | |
|                 msg: "errrequest",
 | |
|                 data: { err: err.request.response },
 | |
|               });
 | |
|             }
 | |
|           });
 | |
|       }
 | |
|     })
 | |
|     .catch((err) => {
 | |
|       //console.log(err.response);
 | |
|       //console.log(err.request);
 | |
|       console.log("checkalias:", err);
 | |
|       if (err.response && err.response.data.msg) {
 | |
|         //remove auth if not well created previously
 | |
|         //console.log(err.response.data.msg);
 | |
|         if (err.response.data.msg == "aliasdoesnotexist") {
 | |
|           delete apx.data.auth;
 | |
|           apx.save();
 | |
|           apx.notification(`#${id} .msginfo`, {
 | |
|             status: 404,
 | |
|             ref: "Pagans",
 | |
|             msg: "aliasdoesnotexist",
 | |
|             data: { alias },
 | |
|           });
 | |
|           //document.getElementById("inputaliasauth").value="";
 | |
|           //document.getElementById("inputpassphraseauth").value="";
 | |
|           //document.getElementById("privatekeyauth").value=""
 | |
|           //window.location.reload();
 | |
|         }
 | |
|         apx.notification(`#${id} .msginfo`, err.response.data);
 | |
|       } else {
 | |
|         apx.notification(`#${id} .msginfo`, {
 | |
|           status: 500,
 | |
|           ref: "Middlewares",
 | |
|           msg: "errrequest",
 | |
|           data: { err },
 | |
|         });
 | |
|       }
 | |
|     });
 | |
| };
 | |
| apx.apxauth.recoverykey = (id, aliasoremail) => {
 | |
|   if (aliasoremail.length < 3) {
 | |
|     apx.notification(`#${id} .msginfo`, {
 | |
|       status: 406,
 | |
|       ref: "Pagans",
 | |
|       msg: "recoveryemailnotfound",
 | |
|       data: { tribe: apx.data.headers.xtribe, search: aliasoremail },
 | |
|     });
 | |
|     return false;
 | |
|   }
 | |
|   const recodata = { tribe: apx.data.headers.xtribe, search: aliasoremail };
 | |
|   const validator= new Checkjson({properties:{email:{type:"string",format:"email"}}});
 | |
|   recodata.emailalias = validator.verify({email:aliasoremail})
 | |
|     ? "email"
 | |
|     : "alias";
 | |
|   document.querySelector(`#${id} .msginfo`).innerHTML = "";
 | |
|   axios
 | |
|     .post(`/api/apxtri/pagans/keyrecovery`, recodata, {
 | |
|       headers: apx.data.headers
 | |
|     })
 | |
|     .then((rep) => {
 | |
|       rep.data.data.search = aliasoremail;
 | |
|       apx.notification(`#${id} .msginfo`, rep.data, true);
 | |
|     })
 | |
|     .catch((err) => {
 | |
|       //console.log("error:", err);
 | |
|       const dataerr =
 | |
|         err.response && err.response.data
 | |
|           ? err.response.data
 | |
|           : { status: 500, ref: "Pagans", msg: "checkconsole", data: {} };
 | |
|       dataerr.data.search = aliasoremail;
 | |
|       apx.notification(`#${id} .msginfo`, dataerr, true);
 | |
|     });
 | |
| };
 | |
| apx.apxauth.generateKey = async (alias, passphrase) => {
 | |
|   /**
 | |
|    * @param {string} alias a unique alias that identify an identity
 | |
|    * @param {string} passphrase a string to cipher the publickey (can be empty, less secure but simpler)
 | |
|    * @return {publickey,privatekey} with userIds = [{alias}]
 | |
|    */
 | |
|   const pgpparam = {
 | |
|     type: "ecc", // Type of the key, defaults to ECC
 | |
|     curve: "curve25519", // ECC curve name, defaults to curve25519
 | |
|     userIDs: [{ alias: alias }], // you can pass multiple user IDs
 | |
|     passphrase: passphrase, // protects the private key
 | |
|     format: "armored", // output key format, defaults to 'armored' (options: 'armored', 'binary' or 'object')
 | |
|   };
 | |
|   const { privateKey, publicKey } = await openpgp.generateKey(pgpparam);
 | |
|   // key start by '-----BEGIN PGP PRIVATE KEY BLOCK ... '
 | |
|   // get liste  of alias:pubklickey await axios.get('api/v0/pagans')
 | |
|   // check alias does not exist
 | |
|   return { alias, privatekey: privateKey, publickey: publicKey };
 | |
| };
 | |
| 
 | |
| apx.apxauth.verifyKeys = async (
 | |
|   publicKeyArmored,
 | |
|   privateKeyArmored,
 | |
|   passphrase
 | |
| ) => {
 | |
|   try {
 | |
|     // Charger la clé publique
 | |
|     const publicKey = await openpgp.readKey({ armoredKey: publicKeyArmored });
 | |
| 
 | |
|     // Charger la clé privée
 | |
|     const privateKey = await openpgp.decryptKey({
 | |
|       privateKey: await openpgp.readPrivateKey({
 | |
|         armoredKey: privateKeyArmored,
 | |
|       }),
 | |
|       passphrase: passphrase, // Passphrase de la clé privée (si nécessaire)
 | |
|     });
 | |
| 
 | |
|     // Créer un message simple à signer
 | |
|     const message = await openpgp.createMessage({ text: "Test message" });
 | |
| 
 | |
|     // Signer le message avec la clé privée
 | |
|     const signedMessage = await openpgp.sign({
 | |
|       message: message, // Message à signer
 | |
|       signingKeys: privateKey, // Clé privée pour signer
 | |
|     });
 | |
| 
 | |
|     // Vérifier la signature avec la clé publique
 | |
|     const verificationResult = await openpgp.verify({
 | |
|       message: await openpgp.readCleartextMessage({
 | |
|         cleartextMessage: signedMessage,
 | |
|       }),
 | |
|       verificationKeys: publicKey, // Clé publique pour vérifier
 | |
|     });
 | |
| 
 | |
|     // Vérifier si la signature est valide
 | |
|     const { verified } = verificationResult.signatures[0];
 | |
|     await verified; // Resolve la promesse
 | |
| 
 | |
|     console.log("Les clés correspondent et sont valides !");
 | |
|     return true;
 | |
|   } catch (error) {
 | |
|     console.error("Erreur lors de la vérification des clés : ", error);
 | |
|     return false;
 | |
|   }
 | |
| };
 | |
| apx.apxauth.testcreatekey = async (alias, passphrase) => {
 | |
|   const pgpparam = {
 | |
|     type: "ecc", // Type of the key, defaults to ECC
 | |
|     curve: "curve25519", // ECC curve name, defaults to curve25519
 | |
|     userIDs: [{ alias: alias }], // you can pass multiple user IDs
 | |
|     passphrase: passphrase, // protects the private key
 | |
|     format: "armored", // output key format, defaults to 'armored' (options: 'armored', 'binary' or 'object')
 | |
|   };
 | |
|   const { privateKey, publicKey } = await openpgp.generateKey(pgpparam);
 | |
| 
 | |
|   console.log(verifyKeys(publicKey, privateKey, passphrase));
 | |
| };
 | |
| apx.apxauth.detachedSignature = async (privK, passphrase, message) => {
 | |
|   /**
 | |
|    * @privK {string} a test priv key
 | |
|    * @passphrase {string} used to read privK
 | |
|    * @message {string} message to sign
 | |
|    * @Return a detached Signature of the message
 | |
|    */
 | |
|   let privatekey;
 | |
|   if (passphrase == "" || passphrase == undefined) {
 | |
|     privatekey = await openpgp.readKey({ armoredKey: privK });
 | |
|   } else {
 | |
|     privatekey = await openpgp.decryptKey({
 | |
|       privateKey: await openpgp.readPrivateKey({ armoredKey: privK }),
 | |
|       passphrase,
 | |
|     });
 | |
|   }
 | |
|   //console.log(message);
 | |
|   const msg = await openpgp.createMessage({ text: message });
 | |
|   //console.log(msg);
 | |
|   const sig = await openpgp.sign({
 | |
|     message: msg,
 | |
|     signingKeys: privatekey,
 | |
|     detached: true,
 | |
|   });
 | |
|   return btoa(sig);
 | |
| };
 | |
| apx.apxauth.clearmsgSignature = async (pubK, privK, passphrase, message) => {
 | |
|   /**
 | |
|    * @privK {string} a test priv key
 | |
|    * @passphrase {string} used to read privK
 | |
|    * @message {string} message to sign
 | |
|    * @Return an base64 Signature of the message or error
 | |
|    */
 | |
|   const publickey = await openpgp.readKey({ armoredKey: pubK });
 | |
|   let privatekey;
 | |
|   if (passphrase == "" || passphrase == undefined) {
 | |
|     privatekey = await openpgp.readKey({ armoredKey: privK });
 | |
|   } else {
 | |
|     privatekey = await openpgp.decryptKey({
 | |
|       privateKey: await openpgp.readPrivateKey({ armoredKey: privK }),
 | |
|       passphrase,
 | |
|     });
 | |
|   }
 | |
|   const cleartextMessage = await openpgp.sign({
 | |
|     message: await openpgp.createCleartextMessage({ text: message }),
 | |
|     signingKeys: privatekey,
 | |
|   });
 | |
|   console.log(cleartextMessage);
 | |
|   const verificationResult = await openpgp.verify({
 | |
|     message: await openpgp.readCleartextMessage({ cleartextMessage }),
 | |
|     verificationKeys: publickey,
 | |
|   });
 | |
| 
 | |
|   const verified = verificationResult.signatures[0];
 | |
|   const validity = await verified.verified;
 | |
|   if (!validity) throw new Error("invalidsignature");
 | |
| 
 | |
|   return btoa(cleartextMessage);
 | |
| };
 | |
| apx.apxauth.authenticatedetachedSignature = async (
 | |
|   alias,
 | |
|   pubK,
 | |
|   detachedSignature,
 | |
|   message
 | |
| ) => {
 | |
|   /**
 | |
|    *  Check that alias (pubkey) sign a message
 | |
|    *  @alias {string} alias link to the publickey
 | |
|    *  @pubK {string} publiKey text format
 | |
|    *  @detachedSignature  {string} a detachedsignatured get from apx.apxauth.detachedSignature
 | |
|    *  @message {string} the message signed
 | |
|    *  @return {boolean} true the message was signed by alias
 | |
|    *                    false the message was not signed by alias
 | |
|    */
 | |
|   const publickey = await openpgp.readKey({ armoredKey: pubK });
 | |
|   const msg = await openpgp.createMessage({ text: message });
 | |
|   const signature = await openpgp.readSignature({
 | |
|     armoredSignature: atob(detachedSignature), // parse detached signature
 | |
|   });
 | |
|   const verificationResult = await openpgp.verify({
 | |
|     msg, // Message object
 | |
|     signature,
 | |
|     verificationKeys: publickey,
 | |
|   });
 | |
|   const { verified, keyID } = verificationResult.signatures[0];
 | |
|   try {
 | |
|     await verified; // throws on invalid signature
 | |
|     //console.log("Signed by key id " + keyID.toHex());
 | |
|     return KeyId.toHex().alias == alias;
 | |
|   } catch (e) {
 | |
|     console.log("Signature could not be verified: " + e.message);
 | |
|     return false;
 | |
|   }
 | |
| };
 | |
| apx.apxauth.createIdentity = async (id, alias, recoemail, passphrase = "") => {
 | |
|   document.querySelector(`#${id} .msginfo`).innerHTML = "";
 | |
|   const aliasregex = /^[a-z0-9]*$/;
 | |
|   //console.log(aliasregex.test(alias));
 | |
|   if (!(alias && alias.length > 3 && aliasregex.test(alias))) {
 | |
|     apx.notification(
 | |
|       `#${id} .msginfo`,
 | |
|       {
 | |
|         status: "406",
 | |
|         ref: "Pagans",
 | |
|         msg: "invalidalias",
 | |
|         data: {},
 | |
|       },
 | |
|       true
 | |
|     );
 | |
|     return false;
 | |
|   }
 | |
|   const validator= new Checkjson({properties:{email:{type:"string",format:"email"}}});
 | |
|   if (recoemail.length > 0 && !validator.verify({email:recoemail})) {
 | |
|     apx.notification(`#${id} .msginfo`, {
 | |
|       status: 406,
 | |
|       ref: "Pagans",
 | |
|       msg: "invalidemail",
 | |
|       data: {},
 | |
|     });
 | |
|     return false;
 | |
|   }
 | |
|   axios
 | |
|     .get(`/api/apxtri/pagans/alias/${alias}`, {
 | |
|       headers: apx.data.headers,
 | |
|     })
 | |
|     .then((rep) => {
 | |
|       console.log(rep);
 | |
|       apx.notification(
 | |
|         `#${id} .msginfo`,
 | |
|         {
 | |
|           ref: "Pagans",
 | |
|           msg: "aliasexist",
 | |
|           data: { alias },
 | |
|         },
 | |
|         true
 | |
|       );
 | |
|     })
 | |
|     .catch(async (err) => {
 | |
|       console.log("checkalias:", err);
 | |
|       if (err.response && err.response.status == 404) {
 | |
|         // alias does not exist create it is possible
 | |
|         const keys = await apx.apxauth.generateKey(alias, passphrase);
 | |
|         apx.data.tmpauth = { ...keys, recoemail, passphrase };
 | |
|         apx.save();
 | |
|         console.log(apx.data.tmpauth);
 | |
|         ["publickey", "privatekey"].forEach((k) => {
 | |
|           console.log(`${id} button.signup${k}`);
 | |
|           const btn = document.querySelector(`#${id} button.signup${k}`);
 | |
|           btn.addEventListener("click", () => {
 | |
|             const blob = new Blob([keys[k]], { type: "text/plain" });
 | |
|             const url = URL.createObjectURL(blob);
 | |
|             const a = document.createElement("a");
 | |
|             a.href = url;
 | |
|             a.download = `${alias}_${k}.txt`;
 | |
|             document.body.appendChild(a);
 | |
|             a.click();
 | |
|             document.body.removeChild(a);
 | |
|           });
 | |
|         });
 | |
|         document
 | |
|           .querySelectorAll(
 | |
|             `#${id} .signupalias, #${id} .signupemailrecovery, #${id} .signuppassphrase`
 | |
|           )
 | |
|           .forEach((e) => e.setAttribute("disabled", "disabled"));
 | |
|         document.querySelector(`#${id} .getmykeys`).classList.remove("hidden");
 | |
|         document.querySelector(`#${id} .btncreatekey`).classList.add("hidden");
 | |
|       } else {
 | |
|         apx.notification(
 | |
|           `#${id} .msginfo`,
 | |
|           {
 | |
|             ref: "Middlewares",
 | |
|             msg: "errrequest",
 | |
|             data: {},
 | |
|           },
 | |
|           true
 | |
|         );
 | |
|       }
 | |
|     });
 | |
| };
 | |
| 
 | |
| /**
 | |
|  *
 | |
|  * @param {string} alias to create
 | |
|  * @param {string} publickey
 | |
|  * @param {string} trustedtribe if none => means no passphrase, no privatekey, no trustedtribe
 | |
|  * @param {string} passphrase
 | |
|  * @param {string} privatekey
 | |
|  * @param {string} email  if none => means no passphrase, no privatekey, no trustedtribe
 | |
|  *
 | |
|  * if email!=none and trustedtribe!= none create a person with parson profil in trustedtribe
 | |
|  * if email!=none and trustedtribe==none then send an email at registration with all element but doi not store in backend for futur recovery
 | |
|  *
 | |
|  */
 | |
| apx.apxauth.test = () => {
 | |
|   //"apx.apxauth.registerIdentity(document.getElementById('inputalias').value,document.getElementById('publickey').document.getElementById('inputpassphrase').value)"
 | |
|   console.log(apx.data.tmpauth);
 | |
| };
 | |
| apx.apxauth.registerIdentity = async (id, trustedtribe) => {
 | |
|   const authid = document.getElementById(id);
 | |
|   console.log("trustedtribe",trustedtribe)
 | |
|   // trustedtribe boolean
 | |
|   //previously store in apx.data.tmpauth={keys:{alias,privatekey,publickey},recoemail,passphrase}
 | |
|   
 | |
|   console.log("tmpauth:",apx.data.tmpauth)
 | |
|   const setheaders = await apx.apxauth.setheadersauth(
 | |
|     apx.data.tmpauth.alias,
 | |
|     apx.data.tmpauth.passphrase,
 | |
|     apx.data.tmpauth.publickey,
 | |
|     apx.data.tmpauth.privatekey,
 | |
|     false
 | |
|   );
 | |
|   if (setheaders.status != 200) {
 | |
|     apx.notification(`#${id} .msginfo`, setheaders);
 | |
|   } else {
 | |
|     // add withpublickeyforcreate to check isAuthenticated alias does not already exist
 | |
| 
 | |
|     const data = {};
 | |
|     data.alias = apx.data.tmpauth.alias;
 | |
|     data.publickey = apx.data.tmpauth.publickey;
 | |
|     if (apx.data.tmpauth.recoemail) {
 | |
|       data.passphrase = apx.data.tmpauth.passphrase;
 | |
|       data.privatekey = apx.data.tmpauth.privatekey;
 | |
|       data.email = apx.data.tmpauth.recoemail;
 | |
|     }
 | |
|     data.trustedtribe = trustedtribe;
 | |
|     console.log(data)
 | |
|     axios
 | |
|       .post(`/api/apxtri/pagans`, data, { headers: apx.data.headers,  withCredentials:true})
 | |
|       .then((reppagan) => {
 | |
|         //console.log(reppagan.data);
 | |
|         apx.notification(`#${id} .msginfo`, reppagan.data);
 | |
|         authid.querySelector(`.btncreateidentity`).classList.add("hidden");
 | |
|         authid.querySelector(`.signupbtnreload`).classList.remove("hidden");
 | |
|         apx.data.headers.xprofils=reppagan.data.profils;
 | |
|         apx.data.save();
 | |
|       })
 | |
|       .catch((err) => {
 | |
|         console.log("error:", err);
 | |
|         const dataerr =
 | |
|           err.response && err.response.data
 | |
|             ? err.response.data
 | |
|             : { status: 500, ref: "Pagans", msg: "", data: {} };
 | |
|         apx.notification(`#${id} .msginfo`, dataerr);
 | |
|       });
 | |
|   }
 | |
| };
 | |
| apx.apxauth.jointribe = (id) => {
 | |
|   /**
 | |
|    * Allow a pagan to register as a person into a tribe
 | |
|    * header must be authenticated with alias into an app belonging to xtribe AND schema person must have apxaccessright with role "pagan": {"C": []}
 | |
|    */
 | |
|   //console.log(apx.data);
 | |
|   if (!apx.data.headers.xprofils.includes("persons")) {
 | |
|     apx.data.headers.xprofils.push("persons");
 | |
|   }
 | |
|   const data = {
 | |
|     alias: apx.data.headers.xalias,
 | |
|     profils: apx.data.headers.xprofils,
 | |
|   };
 | |
|   axios
 | |
|     .put(`/api/apxtri/pagans/person/${apx.data.headers.xtribe}`, data, {
 | |
|       headers: apx.data.headers, withCredentials:true
 | |
|     })
 | |
|     .then((rep) => {
 | |
|       apx.notification(`#${id} .msginfo`, rep.data);
 | |
|       axios
 | |
|         .get(`/api/apxtri/pagans/logout`, {
 | |
|           headers: apx.data.headers, withCredentials:true
 | |
|         })
 | |
|         .then((rep) => {
 | |
|           console.log("logout", rep);
 | |
|           apx.apxauth.authentifyme(
 | |
|             id,
 | |
|             apx.data.auth.alias,
 | |
|             apx.data.auth.passphrase,
 | |
|             apx.data.auth.privatekey
 | |
|           );
 | |
|         })
 | |
|         .catch((err) => {
 | |
|           console.log("Erreur logout check:", err);
 | |
|         });
 | |
|     })
 | |
|     .catch((err) => {
 | |
|       console.log("sorry", err);
 | |
|       if (err.response && err.response.data)
 | |
|         apx.notification("#msginfo", err.response.data);
 | |
|       else
 | |
|         apx.notification("#msginfo", {
 | |
|           status: 500,
 | |
|           ref: "Pagans",
 | |
|           msg: "errcreate",
 | |
|           data: {},
 | |
|         });
 | |
|     });
 | |
| };
 |