349 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			349 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
	
	
const express = require("express");
 | 
						|
const fs = require("fs-extra");
 | 
						|
const dayjs=require('dayjs');
 | 
						|
const path = require("path");
 | 
						|
// Classes
 | 
						|
const Pagans = require("../models/Pagans.js");
 | 
						|
const Odmdb = require("../models/Odmdb.js");
 | 
						|
// Middlewares
 | 
						|
const checkHeaders = require("../middlewares/checkHeaders.js");
 | 
						|
const isAuthenticated = require("../middlewares/isAuthenticated.js");
 | 
						|
 | 
						|
const conf = require(`../../conf/townconf.json`);
 | 
						|
const currentmod = "pagans";
 | 
						|
const log = conf.api.activelog.includes(currentmod);
 | 
						|
 | 
						|
const router = express.Router();
 | 
						|
/**
 | 
						|
 *  /api/models/Pagans.js
 | 
						|
 * 
 | 
						|
 * Managed:
 | 
						|
 | 
						|
/**
 | 
						|
 * Alias exist then return public key or not 
 | 
						|
 * @api {get} /pagans/alias/:alias - alias Get 
 | 
						|
 * @apiName isalias
 | 
						|
 * @apiGroup Pagans
 | 
						|
 * @apiDescription If alias exist return its publickey
 | 
						|
 * 
 | 
						|
 * @param {string} alias 
 | 
						|
 * 
 | 
						|
 * @apiError {json} aliasdoesnotexist  
 | 
						|
 * @apiErrorExample {json}
 | 
						|
 * HTTP/1.1 404 Not Found
 | 
						|
   {"status":404,"ref":"pagans","msg":"aliasdoesnotexist","data": { alias}}
 | 
						|
 *
 | 
						|
 * @apiSuccess {object}  indexfile content
 | 
						|
 * @apiSuccessExample {json} Success-Response:
 | 
						|
 * HTTP/1.1 200 OK
 | 
						|
 * {"status":200, ref:"pagans","msg":"aliasexist","data": { alias, publicKey }}
 | 
						|
 *  *
 | 
						|
 **/
 | 
						|
router.get("/alias/:alias", (req, res) => {
 | 
						|
  const getalias = Pagans.getalias(req.params.alias);
 | 
						|
  res.status(getalias.status).send(getalias);
 | 
						|
});
 | 
						|
/**
 | 
						|
 * @api {get} /pagans/logout - pagan Logout
 | 
						|
 * @apiName Removetoken
 | 
						|
 * @apiGroup Pagans
 | 
						|
 * @apiDescription Remove server's token only the owner of the token (no one else can delete a token )
 | 
						|
 *
 | 
						|
 * @apiSuccess {object}  indexfile content
 | 
						|
 * @apiSuccessExample {json} Success-Response:
 | 
						|
 * HTTP/1.1 200 OK
 | 
						|
 * {status: 200, ref: "Pagans", msg: "logout"
 | 
						|
 *
 | 
						|
 */
 | 
						|
router.get("/logout", checkHeaders, isAuthenticated, (req, res) => {
 | 
						|
  if (log) console.log(currentmod,"Logout:",req.session.header);
 | 
						|
  const logout = Pagans.logout(
 | 
						|
    req.session.header.xalias,
 | 
						|
    req.session.header.xtribe,
 | 
						|
    req.session.header.xdays,
 | 
						|
    req.session.header.xhash
 | 
						|
  );
 | 
						|
  res.status(logout.status).json(logout);
 | 
						|
});
 | 
						|
/**
 | 
						|
 * @api {get} /pagans/isauth  - pagan isAuthenticated?
 | 
						|
 * @apiName isAuth
 | 
						|
 * @apiGroup Pagans
 | 
						|
 * @apiDescription Check if pagan's token is still valid
 | 
						|
 *
 | 
						|
 * @apiError (400) missingheaders
 | 
						|
 * @apiError (400) xaliasdoesnotexist
 | 
						|
 * @apiError (400) signaturefailled
 | 
						|
 * @apiError (401) aliasanonymous
 | 
						|
 * @apiError (404) tribedoesnotexist
 | 
						|
 *
 | 
						|
 * @apiSuccess (200) valid
 | 
						|
 * {object} data contains indexfile requested
 | 
						|
 *
 | 
						|
 */
 | 
						|
router.get("/isauth", checkHeaders, isAuthenticated, (req, res) => {
 | 
						|
  res.status(200).send({
 | 
						|
    status: 200,
 | 
						|
    ref: "headers",
 | 
						|
    msg: "authenticated",
 | 
						|
    data: {
 | 
						|
      xalias: req.session.header.xalias,
 | 
						|
      xprofils: req.session.header.xprofils,
 | 
						|
    },
 | 
						|
  });
 | 
						|
});
 | 
						|
 | 
						|
/**
 | 
						|
 * @api {post} /pagans  - pagan Post
 | 
						|
 * @apiName addpagan
 | 
						|
 * @apiGroup Pagans
 | 
						|
 * @apiDescription
 | 
						|
 *  Create a pagan account from alias, publickey, if trusted recovery =>
 | 
						|
 *  If trustedtribe is true then create a person in xtribe/person/xalias.json with profil.auth={email,privatekey, passphrase}.
 | 
						|
 * 
 | 
						|
 *  Middleware isAuthenticated check that:
 | 
						|
 *  - xhash is well signed from private key linked to the publickey of alias
 | 
						|
 *  - check that alias does not already exist (if yes then verifiedsigne would be false)
 | 
						|
 * Need to wait next block chain to be sure that alias is register in the blokchain
 | 
						|
 * @apiBody {string} alias available (that does not already exist check get /api/alias/:alias that must return 404).
 | 
						|
 * @apiBody {string} publickey  
 | 
						|
 * @apiBody {string} [email] if specified then an email is sent to it with public and privatekey
 | 
						|
 * @apiBody {string} [privatekey]
 | 
						|
 * @apiBody {string} [passphrase] if not specidied => passphrase=""
 | 
						|
 * @apiBody {string} [trustedtribe] the tribename  if not specified then the process will only create a pagan identity, else an item person is create for trustedtribe (that must exist with profil 'person'). To create a person with an existing pagan identity use put /api/person/:alias after authenticated you (headers). In case a person is created then we use all valid other apiBody respecting the persons schema (see put persons)
 | 
						|
 *  @apiBody {object} schema:pagans <a href='/nationchains/schema/pagans.json' target='_blank'>/nationchains/schema/pagans.json</a>
 | 
						|
 * 
 | 
						|
 * @apiError {json} objectNotfound the file does not exist 
 | 
						|
 * @apiErrorExample {json}
 | 
						|
 * HTTP/1.1 404 Not Found
 | 
						|
   {"status":404,"ref":"Odmdb","msg":"pathnamedoesnotexist","data":{indexpath}}
 | 
						|
 *
 | 
						|
 * @apiSuccess {object}  indexfile content
 | 
						|
 * @apiSuccessExample {json} Success-Response:
 | 
						|
 * HTTP/1.1 200 OK
 | 
						|
 * {"status":200, "ref":"Odmdb", "msg":"indexexist", "data":{indexname,content:{index file}}
 | 
						|
 * 
 | 
						|
 */
 | 
						|
router.post("/", checkHeaders, isAuthenticated, async (req, res) => {
 | 
						|
  if (log) console.log(currentmod,"post with", req.body);
 | 
						|
  const role = {
 | 
						|
    xalias: req.session.header.xalias,
 | 
						|
    xprofils: req.session.header.xprofils,
 | 
						|
  };
 | 
						|
  const emailregex =
 | 
						|
  /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
 | 
						|
  if (!(req.body.trustedtribe && req.body.email && emailregex.test(req.body.email) )) {
 | 
						|
   res.status(400).json({status:400,ref:"Pagans",msg:"emailerr", data:{email:req.body.email}})
 | 
						|
   return
 | 
						|
  }
 | 
						|
  const objpagan = { alias: req.body.alias, publickey: req.body.publickey };
 | 
						|
  const newpagan = Odmdb.cud(`../nationchains/pagans`, "C", objpagan, role);
 | 
						|
  const createprocess={status:200, ref:"Pagans", msg:"successfulcreate",data:{alias:req.body.alias}};
 | 
						|
  if (newpagan.status == 200) {
 | 
						|
    if (req.body.email) {
 | 
						|
      const emailsent = await Pagans.sendmailkey({
 | 
						|
       alias: req.body.alias,
 | 
						|
       privatekey: req.body.privatekey,
 | 
						|
       tribe: req.session.header.xtribe,
 | 
						|
       passprhase: req.body.passphrase,
 | 
						|
       publickey: req.body.publickey,
 | 
						|
       email: req.body.email,
 | 
						|
       lg: req.session.header.xlang
 | 
						|
      }
 | 
						|
      );
 | 
						|
      createprocess.data.emailsent = (emailsent.status == 200);
 | 
						|
      createprocess.data.email=req.body.email
 | 
						|
      createprocess.data.tribe=req.session.header.xtribe;
 | 
						|
      if (emailsent.status!=200) {
 | 
						|
        console.log("pagans err to send email emailsent: ",emailsent)
 | 
						|
        createprocess.data.emailerror = emailsent.data.err;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (req.body.trustedtribe) {
 | 
						|
      const persondata = {
 | 
						|
        alias: req.body.alias,
 | 
						|
        owner: req.body.alias,
 | 
						|
        profils: ["pagans", "persons"],
 | 
						|
        recoveryauth: {
 | 
						|
          email: req.body.email,
 | 
						|
          privatekey: req.body.privatekey,
 | 
						|
          publickey: req.body.publickey,
 | 
						|
          passphrase: req.body.passphrase,
 | 
						|
        },
 | 
						|
      };
 | 
						|
      const personup = Odmdb.cud(`../nationchains/tribes/${req.body.trustedtribe}/objects/persons`, "C", persondata, {xprofils:["pagan"],xalias:req.body.alias}); 
 | 
						|
      if (log) console.log(currentmod,'person create',personup)
 | 
						|
      if (personup.status==200){
 | 
						|
        createprocess.data.createperson=true;
 | 
						|
      }else{
 | 
						|
        createprocess.data.createperson=false;
 | 
						|
        createprocess.data.errorperson=true;
 | 
						|
        createprocess.data.errpersonup=personup.data;
 | 
						|
        if (log) console.log(currentmod,"Warning pagan created but person not created and no recovery registration", personup);
 | 
						|
      }
 | 
						|
      res.status(createprocess.status).json(createprocess);
 | 
						|
    }else{
 | 
						|
      res.status(newpagan.status).json(newpagan);
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    //error to create pagan certaily already exist
 | 
						|
    res.status(newpagan.status).json(newpagan);
 | 
						|
  }
 | 
						|
});
 | 
						|
/**
 | 
						|
 * @api {delete} /pagans/alias/:alias - pagan Delete
 | 
						|
 * @apiName deletepagan
 | 
						|
 * @apiGroup Pagans
 | 
						|
 * @apiDescription
 | 
						|
 *  Delete an alias and his publickey, this mean that publickey disapear as well as alias. We set dt_delete
 | 
						|
 * */
 | 
						|
router.delete("/alias/:alias", checkHeaders, isAuthenticated, (req, res) => {
 | 
						|
  const personpath=`../nationchains/pagans`;
 | 
						|
  const role = {
 | 
						|
    xalias: req.session.header.xalias,
 | 
						|
    xprofils: req.session.header.xprofils,
 | 
						|
  };
 | 
						|
  req.session.header.role
 | 
						|
  const delperson = Odmdb.cud(personpath,"U",{alias:req.params.alias,dt_delete:dayjs().toISOString()},role,true);
 | 
						|
  if (log) console.log(currentmod,`DELETE person ${personpath}/${req.params.alias}.json `);
 | 
						|
  if (log) console.log(delperson)
 | 
						|
  res.status(delperson.status).json(delperson);
 | 
						|
 | 
						|
  if (log) console.log(`DELETE pagans nationchains/pagans/${req.params.alias}.json`);
 | 
						|
  const result = Pagans.delete(req.params.alias, req.session.header);
 | 
						|
  res.status(result.status).send(result);
 | 
						|
});
 | 
						|
/**
 | 
						|
 * @api {delete} /pagans/person/:tribe/:alias - person Delete
 | 
						|
 * @apiName deleteperson
 | 
						|
 * @apiGroup Pagans
 | 
						|
 * @apiDescription
 | 
						|
 *  Unsubscribe a person to a tribe => remove a person item and all data link to this alias
 | 
						|
 * @apiHeader {array} xprofils list of profil of authenticated user
 | 
						|
 * @apiHeader {string} xalias current user
 | 
						|
 * @apiParam  {string} tribe where person alias exist
 | 
						|
 * @apiParam   {string} alias to delete as person
 | 
						|
 * */
 | 
						|
router.delete("/person/:tribe/:alias", checkHeaders, isAuthenticated, (req, res) => {
 | 
						|
  const personpath=`../nationchains/tribes/${req.params.tribe}/objects/persons`;
 | 
						|
  const role = {
 | 
						|
    xalias: req.session.header.xalias,
 | 
						|
    xprofils: req.session.header.xprofils,
 | 
						|
  };
 | 
						|
  req.session.header.role
 | 
						|
  const delperson = Odmdb.cud(personpath,"D",{alias:req.params.alias},role,true);
 | 
						|
  if (log) console.log(currentmod,`DELETE person ${personpath}/${req.params.alias}.json `);
 | 
						|
  if (log) console.log(currentmod,"delete person ",delperson)
 | 
						|
  res.status(delperson.status).json(delperson);
 | 
						|
});
 | 
						|
 | 
						|
/**
 | 
						|
 * @api {get} /pagans/person/:alias - person Get
 | 
						|
 * @apiName getpersondata
 | 
						|
 * @apiDescription Get person information from his alias for a xtribe (data and profils per apps)
 | 
						|
 * @apiGroup Pagans
 | 
						|
 *
 | 
						|
 * @apiParam {string} alias
 | 
						|
 *
 | 
						|
 * @apiSuccess (200) personExist
 | 
						|
 * @apiSuccessExample {json}
 | 
						|
 * {status:200, ref:"pagans",msg:"personexist",data: { person } }
 | 
						|
 *
 | 
						|
 * @apiError (404) Notfound
 | 
						|
 * @apiErrorExample {json}
 | 
						|
 *  {status: 404, ref:"pagans",msg:"persondoesnotexist",data: { person } }
 | 
						|
 *
 | 
						|
 * @todo check accessright  for req.session.header.xalias to see if jhe can get person data
 | 
						|
 * if req.param.alias ==  req.session.header.xalias  => Owner
 | 
						|
 * else need accessright to on person  set at R
 | 
						|
 * */
 | 
						|
router.get("/person/:alias", checkHeaders, isAuthenticated, (req, res) => {
 | 
						|
  const getperson=Odmdb.r( `../nationchains/tribes/${req.session.header.xtribe}/objects/persons`,req.params.alias,{ xprofils: req.session.header.xprofils, xalias: req.session.header.xalias })
 | 
						|
  res.status(getperson.status).send(getperson);
 | 
						|
});
 | 
						|
 | 
						|
/**
 | 
						|
 * @api {put} /pagans/person/:tribe - person Put
 | 
						|
 * @apiName updateperson
 | 
						|
 * @apiGroup Pagans
 | 
						|
 * @apiDescription add or update a person = alias in tribe. xalias authenticated (in header) must have a profil with accessright into schema person to create a person.
 | 
						|
 * @apiHeader {string} xhash authenthicate hash with current user keys
 | 
						|
 * @apiHeader {string} xalias current user
 | 
						|
 * @apiHeader {string} xprofils profil list
 | 
						|
 * @apiParam {object} schema:persons <a href='https://smatchit.io/smatchit/schema/persons.json' target='_blank'>https://dnstribe/tribe/schema/persons.json</a>
 | 
						|
 * 
 | 
						|
 */
 | 
						|
router.put("/person/:tribe", checkHeaders, isAuthenticated, (req, res) => {
 | 
						|
  //console.log(req.body);
 | 
						|
  const pathobj=`../nationchains/tribes/${req.params.tribe}/objects/persons`;
 | 
						|
  const action = (fs.existsSync(`${pathobj}/itm/${req.body.alias}.json`))? "U":"C";
 | 
						|
  //set req.body to be in line with schema
 | 
						|
  if (!req.body.profils){
 | 
						|
    req.body.profils=["anonymous","pagans","persons"]
 | 
						|
  }
 | 
						|
  const personup = Odmdb.cud(pathobj, action, req.body, {xprofils:req.session.header.xprofils, xalias:req.session.header.xalias}); 
 | 
						|
  if (log) console.log(currentmod,' personupdate or create:',personup)
 | 
						|
  res.status(personup.status).json(personup);
 | 
						|
});
 | 
						|
 | 
						|
/**
 | 
						|
 * @api {get} /pagans/keyrecovery/:tribe/:email - recovery keys by email
 | 
						|
 * @apiName  recoveryKey
 | 
						|
 * @apiGroup Pagans
 | 
						|
 * @apiDescription Send mails with all registers identities (one per alias where recoveryauth.email is register) 
 | 
						|
 * 
 | 
						|
 * @apiSuccess {object}  send recovery email
 | 
						|
 * @apiSuccessExample {json} Success-Response:
 | 
						|
 * HTTP/1.1 200 OK
 | 
						|
 * {"status":200, "ref":"Pagans", "msg":"recoveryemailsent", "data":{email,tribe,nbalias:'number of alias with this email', nbqent:'number of eamil sent must = nbalias'}}
 | 
						|
 * 
 | 
						|
 * @apiError (404) {string} emailnotfound email does not exist for this tribe
 | 
						|
 * @apiErrorExample {json} 
 | 
						|
 *  {status: 404, ref:"pagans",msg:"emailnotfound",data: { tribe,email } }
 | 
						|
 *
 | 
						|
 */
 | 
						|
router.get("/keyrecovery/:tribe/:email", checkHeaders, (req, res) => {
 | 
						|
  const idxreco=`../../nationchains/tribes/${req.params.tribe}/objects/persons/idx/emailrecovery_alias.json`;
 | 
						|
  if (fs.existsSync(idxreco)){
 | 
						|
    const emailreco = fs.readJSONSync(idxreco);
 | 
						|
    if (emailreco[req.params.email]){
 | 
						|
      let  sentemails=0;
 | 
						|
      emailreco[req.params.email].forEach(alias=>{
 | 
						|
        const ret = Pagans.sendmailkey({alias:alias,tribe:req.params.tribe,lg:req.session.header.xlang})
 | 
						|
        sentemails = (ret.status==200)? sentemails+1:sentemails;
 | 
						|
      })
 | 
						|
      return {status:200,ref:"Pagans",msg:"recoveryemailsent",data:{email:req.params.email,tribe:req.params.tribe,nbalias:emailreco[req.params.email].length, nbsent:sentemails}}
 | 
						|
    }else{
 | 
						|
      return {status:404,ref:"Pagans",msg:"emailnotfound",data:{tribe:req.params.tribe,email:req.params.email}}
 | 
						|
    }
 | 
						|
  }else{
 | 
						|
    return {status:404,ref:"Pagans",msg:"emailnotfound",data:{tribe:req.params.tribe,email:req.params.email}}
 | 
						|
  }
 | 
						|
});
 | 
						|
/**
 | 
						|
 * @api {get} /pagans/keyrecovery/:tribe/:alias - recovery keys by alias
 | 
						|
 * @apiName  recoveryKey
 | 
						|
 * @apiGroup Pagans
 | 
						|
 * @apiDescription Send to email recovery if exist key files 
 | 
						|
 * 
 | 
						|
 * @apiSuccess {object}  send recovery mail for alias
 | 
						|
 * @apiSuccessExample {json} Success-Response:
 | 
						|
 * HTTP/1.1 200 OK
 | 
						|
 * {"status":200, "ref":"Pagans", "msg":"recoveryemailsent", "data":{email,tribe,nbalias:1, nbqent:1 or 0}}
 | 
						|
 * 
 | 
						|
 * @apiError (404) {string} emailnotfound email does not exist for this tribe
 | 
						|
 * @apiErrorExample {json} 
 | 
						|
 *  {status: 404, ref:"pagans",msg:"emailnotfound",data: { tribe,email } }
 | 
						|
 *
 | 
						|
 */
 | 
						|
router.get("/keyrecovery/:tribe/:alias", checkHeaders, (req, res) => {
 | 
						|
  // a tester et revoir
 | 
						|
  const ret = Pagans.sendmailkey({alias:req.params.alias,tribe:req.params.tribe,lg:req.session.header.xlang})
 | 
						|
 if (ret.status==200){
 | 
						|
  return {status:200,ref:"Pagans",msg:"recoveryemailsent",data:{email:"",tribe:req.params.tribe,nbalias:1, nbsent:1}}
 | 
						|
 }else{
 | 
						|
  return {status:404,ref:"Pagans",msg:"emailnotfound",data:{tribe:req.params.tribe,email:req.params.email}}
 | 
						|
 }
 | 
						|
});
 | 
						|
module.exports = router;
 |