113 lines
3.5 KiB
JavaScript

import { Router } from "express";
import axios from "axios";
import { logger, store } from "../../utils/index.js";
import { decode } from "jsonwebtoken";
import jwt from "jsonwebtoken";
import jwkToPem from "jwk-to-pem";
const router = Router();
router.all("/", (req, res, next) => {
var token = null;
var sessionIdentifier = null;
const cookiePrefix = "__Host-VRNTOTCT";
if (req.cookies) {
logger.debug(
`Checking ${cookiePrefix}... Cookie as this takes presidence over Authorization Header ...`
);
Object.keys(req.cookies).forEach((key) => {
if (key.startsWith(cookiePrefix)) {
logger.info(`Found ${key} cookie using value for token`);
token = req.cookies[key];
sessionIdentifier = key.substring(cookiePrefix.length);
}
});
}
if (!token && req.headers.authorization) {
logger.debug("Checking Authorization Header for OIDC_id_token ...");
var authHeader = req.headers.authorization;
const prefix = "OIDC_id_token ";
if (authHeader && authHeader.startsWith(prefix)) {
logger.info("Found OIDC_id_token in Authorization Header");
token = authHeader.substring(prefix.length, authHeader.length);
}
}
if (token) {
const decoded = decode(token);
logger.debug(`Decoded [${JSON.stringify(decoded, null, 2)}]`);
if (decoded.iss) {
const jwkURI = decoded.iss + "/connect/jwk_uri";
logger.debug(`Requesting JWK on ${jwkURI}`);
axios
.get(jwkURI)
.then((jwkResponse) => {
logger.debug(
`Response JWK on ${JSON.stringify(jwkResponse.data, null, 2)}`
);
if (
jwkResponse.data &&
jwkResponse.data.keys &&
jwkResponse.data.keys.length > 0
) {
const key = jwkResponse.data.keys[0];
var pem = jwkToPem(key);
try {
const verified = jwt.verify(token, pem, {
algorithms: [key.alg],
});
logger.debug(`Verified [${JSON.stringify(verified, null, 2)}]`);
const issSplit = verified.iss.split("/oidc-token-service/");
const authData = {
token: token,
host: issSplit[0],
tenant: issSplit[1],
};
const authDataString = JSON.stringify(authData);
logger.info(
`Adding agent ${verified.sub} to store for environment ${authDataString}}`
);
store
.set(verified.sub, authData)
.then(() => {
if (sessionIdentifier && sessionIdentifier.length > 0) {
logger.info(
`Adding sessionIdentifier ${sessionIdentifier} to store for environment ${authDataString}`
);
return store.set(sessionIdentifier, authData);
}
})
.then(() => {
res.send(decoded);
})
.catch((e) => {
logger.error(e); // "Uh-oh!"
});
} catch (err) {
logger.error(`Verify failed [${JSON.stringify(err, null, 2)}].`);
next(err);
}
}
})
.catch((err) => {
logger.error(`JWK Request failed [${JSON.stringify(err, null, 2)}].`);
next(err);
});
}
} else {
next(new Error("Unable to authenticate, no token found"));
}
});
export default router;