1
0
forked from apxtri/apxtri
apxtri/models/Pagans.js

279 lines
8.1 KiB
JavaScript
Raw Normal View History

2023-12-07 12:04:19 +01:00
const glob = require("glob");
const path = require("path");
const dayjs = require("dayjs");
const fs = require("fs-extra");
const axios = require("axios");
2024-06-30 22:06:37 +02:00
const Mustache = require("mustache");
2023-12-07 12:04:19 +01:00
const openpgp = require("openpgp");
const Notifications = require("./Notifications.js");
const Odmdb = require("./Odmdb.js");
const conf = require(`../../../adminapi/objects/tribes/itm/adminapi.json`);
const currentmod = "Pagans";
const log = conf.api.activelog.includes(currentmod);
2023-12-07 12:04:19 +01:00
/**
* Pagan Management numeric Identity and Person (Person = Pagan Id + tribe)
*
*
*
*/
const Pagans = {};
/**
* Remove authentification token after a logout
* @param {string} alias
* @param {string} tribe
* @param {integer} xdays
* @param {string} xhash
* @returns {status:200, ref:"Pagans",msg:"logout"}
* tmpfs name file has to be on line with the tmpfs create by isAuthenticated
* tmpfs contain profils name for a tribe/
*/
Pagans.logout = (alias, tribe, xdays, xhash) => {
//console.log(alias, tribe, xdays, xhash);
// inline with middleware isAuthenticated.js
2024-05-29 11:21:15 +02:00
let tmpfs = `../../tmp/tokens/${alias}_${tribe}_${xdays}`;
2023-12-07 12:04:19 +01:00
//max filename in ext4: 255 characters
tmpfs += `_${xhash.substring(150, 150 + tmpfs.length - 249)}.json`;
fs.remove(tmpfs);
2024-06-30 22:06:37 +02:00
if (log) console.log(currentmod, "logout token", tmpfs);
2023-12-07 12:04:19 +01:00
return { status: 200, ref: "Pagans", msg: "logout" };
};
2024-09-04 09:06:17 +02:00
/**
* Recovery keys by email or by alias and send one mail per alias
* @Param emailalias (2 options email or alias)
* @Param tribe and existing tribe on this serveur
* @Param search a text string to looking for (as email or as alias)
* @Param lg language to send email
*/
Pagans.keyrecovery = (emailalias, tribe, search, lg) => {
2024-09-24 14:41:06 +02:00
if (log)
console.log(
currentmod,
":try to recover emailalias, tribe, search, lg:",
emailalias,
tribe,
search,
lg
);
2024-09-04 09:06:17 +02:00
if (!["email", "alias"].includes(emailalias)) {
return {
status: 406,
ref: "Pagans",
msg: "emailaliasnotemailoralias",
data: {},
};
}
let emaillist = [];
if (emailalias == "email") {
search = search.toLowerCase();
const idxreco = `../../${tribe}/objects/persons/idx/emailrecovery_alias.json`;
if (fs.existsSync(idxreco)) {
const emailreco = fs.readJSONSync(idxreco);
const listalias = emailreco[search] ? emailreco[search] : [];
listalias.forEach((a) => {
emaillist.push({ alias: a, tribe, lg });
});
}
} else {
const personpath = `../../${tribe}/objects/persons/itm/${search}.json`;
2024-09-24 14:41:06 +02:00
2024-09-04 09:06:17 +02:00
if (fs.existsSync(personpath)) {
2024-09-24 14:41:06 +02:00
const person = fs.readJSONSync(personpath);
if (person.recoveryauth) emaillist.push({ alias: search, tribe, lg });
2024-09-04 09:06:17 +02:00
}
}
emaillist.forEach((e) => {
const ret = Pagans.sendmailkey(e);
2024-09-04 09:06:17 +02:00
});
if (emaillist.length > 0) {
return {
status: 200,
ref: "Pagans",
msg: "recoveryemailsent",
data: { numberemailsent: emaillist.length },
};
}
return {
status: 404,
ref: "Pagans",
msg: "recoveryemailnotfound",
data: { tribe },
};
};
2023-12-07 12:04:19 +01:00
/**
* @param {string} alias a alias that exist or not
* @return {object} { status: 200, ref:"pagans",msg:"aliasexist",data: { alias, publicKey } }
* { status: 404, ref:"pagans",msg:"aliasdoesnotexist",data: { alias} }
*
**/
Pagans.getalias = (alias) => {
//bypass Odmdb cause all is public save ressources
2024-06-30 22:06:37 +02:00
console.log(path.resolve(`../objects/pagans/itm/${alias}.json`));
2024-03-15 08:49:23 +01:00
if (fs.existsSync(`../objects/pagans/itm/${alias}.json`)) {
2023-12-07 12:04:19 +01:00
return {
status: 200,
ref: "Pagans",
msg: "aliasexist",
2024-06-30 22:06:37 +02:00
data: fs.readJSONSync(`../objects/pagans/itm/${alias}.json`),
2023-12-07 12:04:19 +01:00
};
} else {
return {
status: 404,
ref: "Pagans",
msg: "aliasdoesnotexist",
data: { alias },
};
}
};
/**
* Send email with alias's keys to email or person alias person.recovery.email
*
* If email or pubkey is undefined then get data from tribe/person(alias)
* Send email with keys
* @param {object} data
* @param {string} data.alias
* @param {pgpPrivate} [data.privatekey]
* @param {string} [data.passphrase]
* @param {string} data.tribe
* @param {pgpPublic} [data.publickey]
* @param {string} [data.email]
* @param {string} data.lg
*/
Pagans.sendmailkey = (data) => {
2024-06-30 22:06:37 +02:00
if (log)
console.log(
currentmod,
data.alias,
"-",
data.privatekey ? data.privatekey.substring(0, 10) : "",
"-",
data.tribe,
"-",
data.passphrase,
"-",
data.publickey ? data.publickey.substring(0, 10) : "",
"-",
data.email,
"-",
data.lg
);
const person = {
alias: data.alias,
privatekey: data.privatekey,
tribe: data.tribe,
};
2023-12-07 12:04:19 +01:00
if (!data.publickey || !data.email || !data.privatekey) {
2024-03-15 08:49:23 +01:00
const personfile = `../../${data.tribe}/objects/persons/itm/${data.alias}.json`;
2023-12-07 12:04:19 +01:00
if (!fs.existsSync(personfile)) {
return {
status: 404,
ref: "Pagans",
msg: "persondoesnotexist",
2024-06-30 22:06:37 +02:00
data: { alias: data.alias, tribe: data.tribe },
2023-12-07 12:04:19 +01:00
};
}
2024-06-30 22:06:37 +02:00
const persondata = fs.readJsonSync(personfile);
if (!persondata.recoveryauth) {
2024-06-08 15:44:00 +02:00
return {
2024-06-30 22:06:37 +02:00
status: 404,
ref: "Pagans",
msg: "personhasnorecoveryauth",
data: { alias: data.alias, tribe: data.tribe, email: data.email },
};
2024-06-08 15:44:00 +02:00
}
2023-12-07 12:04:19 +01:00
person.email = persondata.recoveryauth.email;
person.publickey = persondata.recoveryauth.publickey;
person.privatekey = persondata.recoveryauth.privatekey;
person.passphrase = persondata.recoveryauth.passphrase;
} else {
person.email = data.email;
person.passphrase = data.passphrase;
person.publickey = data.publickey;
}
2024-06-30 22:06:37 +02:00
person.avecpassphrase = person.passphrase != "";
let tplfile = `../../${data.tribe}/template/createidentity_${data.lg}.js`;
if (!fs.existsSync(tplfile)) {
tplfile = `../template/createidentity_${data.lg}.js`;
if (!fs.existsSync(tplfile)) {
2024-02-20 14:52:07 +01:00
return {
2024-06-30 22:06:37 +02:00
status: 406,
ref: "Pagans",
msg: "templatedoesnotexist",
data: { tplfile },
};
2024-02-20 14:52:07 +01:00
}
}
2024-06-30 22:06:37 +02:00
const tplemail = require(path.resolve(tplfile));
2024-05-23 19:06:05 +02:00
/*
Remove from attachments for less user confusing
{
filename:`${person.alias}_publickey.txt`,
content: person.publickey,
contentType:"text/plain"
},
*/
2023-12-07 12:04:19 +01:00
const maildata = {
2024-06-30 22:06:37 +02:00
from: tplemail.sender,
2023-12-07 12:04:19 +01:00
to: person.email,
subject: Mustache.render(tplemail.subject, person),
html: Mustache.render(tplemail.html, person),
text: Mustache.render(tplemail.text, person),
attachments: [
{
2024-06-30 22:06:37 +02:00
filename: `${person.alias}_privatekey.txt`,
2023-12-07 12:04:19 +01:00
content: person.privatekey,
2024-06-30 22:06:37 +02:00
contentType: "text/plain",
},
],
2023-12-07 12:04:19 +01:00
};
return Notifications.sendmail(maildata, data.tribe);
};
Pagans.authenticatedetachedSignature = async (
alias,
pubK,
detachedSignature,
message
) => {
/**
* Check that a message was signed with a privateKey from a publicKey
* This is not necessary if isAuthenticated, but can be usefull to double check
* @TODO finish it and implement it also in /apxpagan.js for browser
* @alias {string} alias link to the publicKey
* @pubK {string} publiKey text format
* @detachedSignature {string} a detachedsignatured get from apx.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: 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
2024-06-30 22:06:37 +02:00
if (log) console.log(currentmod, "Signed by key id " + keyID.toHex());
2023-12-07 12:04:19 +01:00
return KeyId.toHex().alias == alias;
} catch (e) {
2024-06-30 22:06:37 +02:00
if (log)
console.log(currentmod, "Signature could not be verified: " + e.message);
2023-12-07 12:04:19 +01:00
return false;
}
};
module.exports = Pagans;