forked from apxtri/apxtri
476 lines
17 KiB
JavaScript
Executable File
476 lines
17 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.json`);
|
|
const currentmod = "pagans";
|
|
const log = conf.api.activelog.includes(currentmod);
|
|
|
|
const router = express.Router();
|
|
|
|
/**
|
|
* Alias exist then return public key or not
|
|
* @api {get} adminapi/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} adminapi/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} adminapi/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} adminapi/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)
|
|
*
|
|
* @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 };
|
|
console.log(path.resolve(`../objects/pagans`));
|
|
const newpagan = Odmdb.cud(`../objects/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: ["anonymous", "pagans", "persons"],
|
|
recoveryauth: {
|
|
email: req.body.email,
|
|
privatekey: req.body.privatekey,
|
|
publickey: req.body.publickey,
|
|
passphrase: req.body.passphrase,
|
|
},
|
|
};
|
|
const personup = Odmdb.cud(
|
|
`../../${req.body.trustedtribe}/objects/persons`,
|
|
"C",
|
|
persondata,
|
|
{ xprofils: ["anonymous", "pagans"], 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} adminapi/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 = `../objects/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 /api/adminapi/objects/pagans/${req.params.alias}.json`
|
|
);
|
|
const result = Pagans.delete(req.params.alias, req.session.header);
|
|
res.status(result.status).send(result);
|
|
});
|
|
/**
|
|
* @api {delete} adminapi/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. An asynchrone process turn each day to clean data in tribe, if a persons does not exist anymore in the tribe. Pagans alias is still existing as it is autonomous. It is possible to delete pagans see "pagan Delete".
|
|
* @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 = `../../${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} adminapi/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) => {
|
|
console.log(
|
|
path.resolve(`../../${req.session.header.xtribe}/objects/persons`)
|
|
);
|
|
const getperson = Odmdb.r(
|
|
`../../${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} adminapi/pagans/person/:tribe - person Put
|
|
* @apiName updateperson
|
|
* @apiGroup Pagans
|
|
* @apiDescription add a person = alias in tribe. xalias must be authenticated. This end point have to be use the first time a person is create then use item Update PUT /api/adminapi/odmdb/itm/:tribe/persons.<br> This endpoint is the only way to change profils of a person by itself (authenitcated alias = person.alias) and can be done only with req.body.addprofils req.body.removeprofils.
|
|
* @apiHeader {string} xhash authenthicate hash with current user keys
|
|
* @apiHeader {string} xalias current user
|
|
* @apiHeader {string} xprofils profil list
|
|
* @apiParam {string} tribe an existing tribe
|
|
* @apiBody {object} schema:persons <a href='https://smatchit.io/smatchit/schema/persons.json' target='_blank'>https://dnstribe/tribe/schema/persons.json</a>
|
|
* @apiBody {string} [addprofils] must be alone no other Body field
|
|
* @apiBody {string} [removeprofils] must be alone
|
|
*/
|
|
router.put("/person/:tribe", checkHeaders, isAuthenticated, (req, res) => {
|
|
//console.log(req.body);
|
|
const pathobj = `../../${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 (
|
|
action == "U" &&
|
|
((req.body.addprofils &&
|
|
["seekers", "recruiters", "adminrecruiters"].includes(
|
|
req.body.addprofils
|
|
)) ||
|
|
(req.body.removeprofils &&
|
|
["seekers", "recruiters", "adminrecruiters"].includes(
|
|
req.body.removeprofils
|
|
)))
|
|
) {
|
|
const person = fs.readJsonSync(`${pathobj}/itm/${req.body.alias}.json`);
|
|
if (!person.profils.includes(req.body.addprofils)) {
|
|
if (req.body.addprofils) {
|
|
person.profils.push(req.body.addprofils);
|
|
}
|
|
if (
|
|
req.body.removeprofils &&
|
|
person.profils.includes(req.body.removeprofils)
|
|
) {
|
|
person.profils = person.profils.filter(
|
|
(e) => e !== req.body.removeprofils
|
|
);
|
|
Odmdb.cud(
|
|
`../../${req.params.tribe}/objects/${req.body.removeprofils}`,
|
|
"D",
|
|
{ alias: req.body.alias },
|
|
{
|
|
xprofils: req.session.header.xprofils,
|
|
xalias: req.session.header.xalias,
|
|
}
|
|
);
|
|
}
|
|
}
|
|
person.dt_update = dayjs().toISOString();
|
|
fs.outputJSONSync(`${pathobj}/itm/${req.body.alias}.json`, person);
|
|
//console.log(person)
|
|
res.status(200).json({
|
|
status: 200,
|
|
ref: "Pagans",
|
|
msg: "profilupdate",
|
|
data: { alias: person.alias, profils: person.profils },
|
|
});
|
|
}
|
|
if (!req.body.addprofils && !req.body.removeprofils) {
|
|
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 {post} /adminapi/pagans/keyrecovery - recovery keys
|
|
* @apiName recoveryKey
|
|
* @apiGroup Pagans
|
|
* @apiDescription Send mails with all registers identities (one per alias where recoveryauth.email is register). Search can be request by email or by alias for a tribe. It is looking for in person.recoveryauth.email to send keys. One mail is sent by alias. So if n alias has the same recoveryaut.email then it will send n email.
|
|
* @apiBody {string} emailalias type of search (email or alias)
|
|
* @apiBody {string} tribe tribename into looking for
|
|
* @apiBody {string} search a text containing email or an alias to looking for
|
|
*
|
|
* @apiSuccess {object} send recovery email
|
|
* @apiSuccessExample {json} Success-Response:
|
|
* HTTP/1.1 200 OK
|
|
* {"status":200, "ref":"Pagans", "msg":"recoveryemailsent", "data":{email,tribe,numberemailsent'}}
|
|
*
|
|
* @apiError (404) {string} recoveryemailnotfound email does not exist for this tribe
|
|
* @apiErrorExample {json}
|
|
* {status: 404, ref:"pagans",msg:"recoveryemailnotfound",data: { tribe,email } }
|
|
*
|
|
*/
|
|
router.post("/keyrecovery", checkHeaders, (req, res) => {
|
|
const recores=Pagans.keyrecovery(req.body.emailalias,req.body.tribe,req.body.search,req.session.header.xlang)
|
|
res.status(recores.status).json(recores);
|
|
/*
|
|
let emailist = [];
|
|
let alias = req.body.search;
|
|
if (req.body.emailalias == "email") {
|
|
req.body.search = req.body.search.toLowerCase();
|
|
const idxreco = `../../${req.body.tribe}/objects/persons/idx/emailrecovery_alias.json`;
|
|
if (fs.existsSync(idxreco)) {
|
|
const emailreco = fs.readJSONSync(idxreco);
|
|
const listalias = emailreco[req.body.search]
|
|
? emailreco[req.body.search]
|
|
: [];
|
|
listalias.forEach((a) => {
|
|
emailist.push({
|
|
alias: a,
|
|
tribe: req.body.tribe,
|
|
lg: req.session.header.xlang,
|
|
});
|
|
});
|
|
}
|
|
} else if (req.body.emailalias == "alias") {
|
|
const falias = `../../${req.body.tribe}/objects/persons/itm/${req.body.search}.json`;
|
|
if (fs.existsSync(falias)) {
|
|
emailist.push({
|
|
alias: req.body.search,
|
|
tribe: req.body.tribe,
|
|
lg: req.session.header.xlang,
|
|
});
|
|
}
|
|
} else {
|
|
res.status(406).json({status:406,ref:"Pagans",msg:"emailaliasnotemailoralias",data:{}})
|
|
}
|
|
|
|
emailist.forEach((e) => {
|
|
console.log(e);
|
|
const ret = Pagans.sendmailkey(e);
|
|
});
|
|
|
|
if (emailist.length > 0) {
|
|
res.status(200).json({
|
|
status: 200,
|
|
ref: "Pagans",
|
|
msg: "recoveryemailsent",
|
|
data: { numberemailsent: emailist.length },
|
|
});
|
|
} else {
|
|
res.status(404).json({
|
|
status: 404,
|
|
ref: "Pagans",
|
|
msg: "recoveryemailnotfound",
|
|
data: { tribe: req.body.tribe },
|
|
});
|
|
}
|
|
*/
|
|
});
|
|
|
|
module.exports = router;
|