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;