apxtrib/api/middlewares/isAuthenticated.js

119 lines
4.0 KiB
JavaScript
Executable File

const fs = require("fs-extra");
const dayjs = require("dayjs");
const glob = require("glob");
const openpgp = require("openpgp");
const conf = require(`${process.env.dirtown}/conf.json`);
const isAuthenticated = async (req, res, next) => {
// tokens if valid are store in /dirtown/tmp/tokens/xalias_xdays_xhash(20,200)
// once a day rm oldest tokens than 24hours tag job by adding tmp/tokensmenagedone{day}
const currentday = dayjs().date();
console.log(
"if menagedone" + currentday,
!fs.existsSync(`${process.env.dirtown}/tmp/tokensmenagedone${currentday}`)
);
if (!fs.existsSync(`${process.env.dirtown}/tmp/tokens`))
fs.mkdirSync(`${process.env.dirtown}/tmp/tokens`);
if (!fs.existsSync(`${process.env.dirtown}/tmp/tokensmenagedone${currentday}`)) {
// clean oldest
const tsday = dayjs().valueOf(); // now in timestamp format
glob.sync(`${process.env.dirtown}/tmp/tokensmenagedone*`).forEach((f) => {
fs.removeSync(f);
});
glob.sync(`${process.env.dirtown}/tmp/tokens/*.json`).forEach((f) => {
if (tsday - parseInt(f.split("_")[1]) > 86400000) fs.remove(f);
});
}
//Check register in tmp/tokens/
console.log("isAuthenticate?");
const resnotauth = {
ref: "headers",
msg: "notauthenticated",
data: {
xalias: req.session.header.xalias,
xaliasexists: true,
},
};
//console.log(req.session.header);
if (req.session.header.xalias == "anonymous" || req.session.header.xhash == "anonymous") {
console.log("alias anonymous means not auth");
return res.status(401).json(resnotauth);
}
const tmpfs = `${process.env.dirtown}/tmp/tokens/${req.session.header.xalias}_${
req.session.header.xdays
}_${req.session.header.xhash.substring(20, 200)}`;
//console.log(tmpfs);
if (!fs.existsSync(tmpfs)) {
// need to check detached sign
let publickey;
if (
fs.existsSync(
`${conf.dirapi}/nationchains/pagans/itm/${req.session.header.xalias}.json`
)
) {
const pagan = fs.readJsonSync(
`${conf.dirapi}/nationchains/pagans/itm/${req.session.header.xalias}.json`
);
publickey = pagan.publicKey;
} else {
resnotauth.data.xaliasexists = false;
if (req.body.publickey) {
publickey = req.body.publickey;
} else {
console.log("alias unknown");
return res.status(404).send(resnotauth);
}
}
if (publickey.substring(0,10)!=="-----BEGIN"){
console.log("Publickey is not valid as armored key:", publickey)
return res.status(404).send(resnotauth);
}
if (Buffer.from(req.session.header.xhash, "base64").toString().substring(0,10)!=="-----BEGIN"){
console.log("xhash conv is not valid as armored key:", Buffer.from(req.session.header.xhash, "base64").toString())
return res.status(404).send(resnotauth);
}
let publicKey;
try {
publicKey = await openpgp.readKey({ armoredKey: publickey });
}catch(err){
console.log(erreur)
}
const msg = await openpgp.createMessage({
text: `${req.session.header.xalias}_${req.session.header.xdays}`,
});
const signature = await openpgp.readSignature({
armoredSignature: Buffer.from(
req.session.header.xhash,
"base64"
).toString(),
});
//console.log(msg);
//console.log(signature);
//console.log(publicKey);
const checkauth = await openpgp.verify({
message: msg,
signature: signature,
verificationKeys: publicKey,
});
//console.log(checkauth);
//console.log(checkauth.signatures[0].keyID);
//console.log(await checkauth.signatures[0].signature);
//console.log(await checkauth.signatures[0].verified);
const { check, keyID } = checkauth.signatures[0];
try {
await check; // raise an error if necessary
fs.outputFileSync(tmpfs, req.session.header.xhash, "utf8");
} catch (e) {
resnotauth.msg = "signaturefailed";
console.log("not auth fail sign");
return res.status(401).send(resnotauth);
}
}
console.log("Authenticated");
next();
};
module.exports = isAuthenticated;