citi-hub-session-engine
Version:
Module for authentication methods for CITI hub
124 lines (99 loc) • 4.62 kB
JavaScript
const { configurations_key } = require("../utils/Constants");
const { logger } = require("../utils/Logger");
const fetch = require("node-fetch");
const { setUserTransactionContext } = require("../utils/transactionContext");
const { publicEncrypt, createDecipheriv, privateDecrypt } = require("crypto");
const validate = async (token) => {
// Aquí puedes añadir tu lógica de validación del token
// Por ejemplo, decodificar un JWT, buscar el token en la base de datos, etc.
//const isValid = validateToken(token); // Implementa esta función según tu lógica
const config = global[configurations_key];
const endpointValidate = config.validate.endpoint;
logger.info(`endpointValidate ${endpointValidate} `);
//INVOKE ENDPOINT VALIDATE, POST, headers: {company: config.company, provider: 'device'}
const response = await fetch(endpointValidate, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: token,
},
})
.then((res) => res.json())
.catch((error) => console.error("error", error));
if (response.code !== 200) {
logger.error("Error on validate token", response);
return {
isValid: false,
user: null,
};
}
setUserTransactionContext(response.user);
return {
isValid: true,
user: response.user,
};
};
const bearerCryptData = (server, options) => {
return {
authenticate: async (_req, _h) => {
try {
logger.info(`Bearer schema strategy`);
//get token from header
logger.info("Get token from header");
const tokenHe = _req.headers.authorization;
logger.info(`tokenHeader ${tokenHe} `);
logger.info("Get configurations for module");
//get configurations for global variable
const config = global[configurations_key];
logger.info("SessionEngine configurations", config);
if (undefined === config || null === config) {
logger.error("sessionEngine configurations not found");
return _h.response({ code: 500, message: "sessionEngine configurations not found" }).code(500);
}
if (!tokenHe) {
throw _h.response({ code: 400, message: "header bearer 'token' is required" }).code(400);
}
const valid = await validate(tokenHe);
if (!valid.isValid) {
return _h.response({ code: 401, message: "Invalid token" }).code(401);
}
//en este caso el body esta cifrado.
//decrypt body
logger.info(valid.user);
const privateKey = valid.user.client.privatekey;
const publicKey = valid.user.client.publickey;
const aesKey = Buffer.from(valid.user.client.aeskey, "hex");
const iv = Buffer.from(valid.user.client.iv, "hex");
logger.info(`privateKey ${privateKey} `);
logger.info(`publicKey ${publicKey} `);
logger.info(`aesKey ${aesKey} `); // Hexadecimal
logger.info(`iv ${iv} `); // Hexadecimal
// Encriptar la clave AES con la llave pública RSA
const encryptedAesKey = publicEncrypt(publicKey, aesKey);
logger.info("encryptedAesKey", encryptedAesKey);
logger.info(_req);
logger.info(_req._route.settings.validate.payload);
const encryptedData = _req.payload;
logger.info(`Encrypted Data: ${encryptedData} `); // `encryptedData` es un string en base64 que representa el cuerpo de la solicitud cifrado con AES-256-CBC y la clave `aesKey` y el IV `iv
logger.info("Encrypted AES Key:", encryptedAesKey.toString("base64"));
logger.info("IV:", iv.toString("base64"));
const decryptedAesKey = privateDecrypt(privateKey, encryptedAesKey);
// Desencriptar los datos con AES
const decipher = createDecipheriv("aes-256-cbc", decryptedAesKey, iv);
let decryptedData = decipher.update(encryptedData, "base64", "utf8");
decryptedData += decipher.final("utf8");
logger.info("Decrypted Data:", decryptedData);
// Si la validación es exitosa, continúa con el request
// Puedes adjuntar información al request.auth.credentials si es necesario
return _h.authenticated({
credentials: valid,
data: JSON.parse(decryptedData),
});
} catch (error) {
logger.error("Error on bearer schema strategy", error);
throw _h.response({ code: 500, message: "Internal error" }).code(500);
}
},
};
};
module.exports = bearerCryptData;