mock-jwks
Version:
A tool to mock a JWKS for development of microservices who consume jwts signed with RSA
144 lines (131 loc) • 7.53 kB
JavaScript
import {http as $bHgEm$http, HttpResponse as $bHgEm$HttpResponse} from "msw";
import {setupServer as $bHgEm$setupServer} from "msw/node";
import {createHash as $bHgEm$createHash} from "node:crypto";
import {encode as $bHgEm$encode} from "base64-url";
import $bHgEm$jsonwebtoken from "jsonwebtoken";
import $bHgEm$nodeforge from "node-forge";
import $bHgEm$nodersa from "node-rsa";
/* HARDCODED MOCK RSA KEYS */ const $2e261e4cdbe2c032$var$PRIVATE_KEY_PEM = "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEApoocpO3bbUF6o8eyJlQCfwLahEsunWdVF++yOEyKu4Lp1j0m\n2j/P7iHOtxBAkjdM2X2oW3qO1mR0sIFefqnm93g0q2nRuYEoS+W3o6X50wjOVm8f\nr/tLqELzy5BoET0AQl7Axp1DNsb0HNOBcoIBt+xVY4I+k6uXJJJMzbgvahAgSLZ9\nRW0Z0WT+dCHZpZUj0nLxNXIPdci65Bw6IognqXHP6AwKZXpT6jCzjzq9uyHxVcud\nqw6j0kQw48/A5A6AN5fIVy1cKnd0sKdqRX1NUqVoiOrO4jaDB1IdLD+YmRE/JjOH\nsWIMElYCPxKqnsNo6VCslGX/ziinArHhqRBrHwIDAQABAoIBAHAdmpsN5iLvafjI\nf45+EBAhg6p8Uq102zx6CakNHniN8Y5hLL7RJtJRwDBNqKrGv93LUoQDRhXfGw+Y\niF0NVIhVTF/5pU8VPGOcCr0JB96ilwZpWRPIQW7NZAMu/GBeiMYls/IB/TXrSnv9\nh6/nBfEkEXgkPqx7YA0m0L3NuV3U1lCY/LhBJY4Xvi0uRdqu3tTHXftehuPwC4UB\n42eJTWv/qLeOlkCdUUV4f7+dNaES88Vdhj6lu/BusnNhvnwHQik4dNwzPCGeP8NV\n5gaesWiNWFZuTURGKk1B65p5LzNPjsVT50RDuW8FnSZwIvNcohrX9ILPsmg/t0Kr\nozcOksECgYEA4XWOK4twx5RG162zveRHqU7H9RBWSz7/PzM9Eob9vx/tC/b1YqBR\nVShk23vje19eNiYWAkxcpobIP4ek/0ZT8nHkJg8wl+J/hnXADcvwv2dKnoFnm5pn\nrTBUKc8R3wrSlAV8XQAtdnxsfFa5AOQJ6WFVI9AdfH3Iw8XZk4gIIPMCgYEAvRlY\ny80HnR3kwMOqY488V1qk41dmfNqa+YDL+zkPF1HhHI9VnK5BQuI7lyKJl984KwHu\n0gbwx3Wp4XkD5JUboEpl5LnaLsjEWemjTaQWdvJHPd5wkJ0m/jRQ2YeT4g2gFu4y\nPi/pWkrzhnzQQVAmOdAm5Kj27LtDzp0lspw3uCUCgYEAw2YdvFGSgfZZW4147QeO\nsAbON+9bysUjdMPUl10VR/LEgA0d6MdnFfX3S13Y7tDdlvJ1OrKxzcWcgaru7ism\nkEXy5KVfiRNNUNx2gb6RvWEpA6zFfc9ZMXlkSAPlyjfX/1+tw/Bmdn0pjK2gk0wP\n5wtrPameFInzWPD9O+a2nM8CgYBZ6UhgNs+M9B7FTQOiLQPa4R2PfwobCXIwef4D\nKIE1bFgl1T02r2AWZi1BUkmr7ZXuVQ/xyx0HKbopm/mu4PruvxEtrPTB0/IQcleU\nXhXUXqRjFXXePOrCaaubkqxNCn95B67aBLvmk8awxn3a4DocuQ0VIgWuT+gQwIWh\nJEgWBQKBgQDKD+2Yh1/rUzu15lbPH0JSpozUinuFjePieR/4n+5CtEUxWJ2f0WeK\ns4XWWf2qgUccjpiGju2UR840mgWROoZ8BfSTd5tg1F7bo0HMgu2hu0RIRpZcRhsA\nCd0GrJvf1t0QIdDCXAy+RpgU1SLSq4Q6Lomc0WA5C5nBw9RKEUOV9A==\n-----END RSA PRIVATE KEY-----\n";
const $2e261e4cdbe2c032$var$PUBLIC_KEY_PEM = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApoocpO3bbUF6o8eyJlQC\nfwLahEsunWdVF++yOEyKu4Lp1j0m2j/P7iHOtxBAkjdM2X2oW3qO1mR0sIFefqnm\n93g0q2nRuYEoS+W3o6X50wjOVm8fr/tLqELzy5BoET0AQl7Axp1DNsb0HNOBcoIB\nt+xVY4I+k6uXJJJMzbgvahAgSLZ9RW0Z0WT+dCHZpZUj0nLxNXIPdci65Bw6Iogn\nqXHP6AwKZXpT6jCzjzq9uyHxVcudqw6j0kQw48/A5A6AN5fIVy1cKnd0sKdqRX1N\nUqVoiOrO4jaDB1IdLD+YmRE/JjOHsWIMElYCPxKqnsNo6VCslGX/ziinArHhqRBr\nHwIDAQAB\n-----END PUBLIC KEY-----\n";
const $2e261e4cdbe2c032$export$67b9d010cfffa653 = ({ publicKey: publicKey, privateKey: privateKey, jwksOrigin: jwksOrigin })=>{
const cert = (0, $bHgEm$nodeforge).pki.createCertificate();
cert.publicKey = publicKey;
cert.serialNumber = '123';
const attrs = [
{
name: 'commonName',
value: `${jwksOrigin}`
}
];
cert.validity.notBefore = new Date();
cert.validity.notAfter = new Date();
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1);
cert.setSubject(attrs);
cert.sign(privateKey, (0, $bHgEm$nodeforge).md.sha256.create());
return (0, $bHgEm$nodeforge).pki.certificateToPem(cert);
};
const $2e261e4cdbe2c032$var$getCertThumbprint = (certificate)=>{
const shasum = (0, $bHgEm$createHash)('sha1');
const der = Buffer.from(certificate).toString('binary');
shasum.update(der);
return shasum.digest('base64');
};
const $2e261e4cdbe2c032$export$ee715dcb214d41eb = ({ privateKey: privateKey, publicKey: publicKey, jwksOrigin: jwksOrigin })=>{
const helperKey = new (0, $bHgEm$nodersa)();
helperKey.importKey((0, $bHgEm$nodeforge).pki.privateKeyToPem(privateKey));
const { n: modulus, e: exponent } = helperKey.exportKey('components');
const certPem = $2e261e4cdbe2c032$export$67b9d010cfffa653({
jwksOrigin: jwksOrigin,
privateKey: privateKey,
publicKey: publicKey
});
const certDer = (0, $bHgEm$nodeforge).util.encode64((0, $bHgEm$nodeforge).asn1.toDer((0, $bHgEm$nodeforge).pki.certificateToAsn1((0, $bHgEm$nodeforge).pki.certificateFromPem(certPem))).getBytes());
const thumbprint = $bHgEm$encode($2e261e4cdbe2c032$var$getCertThumbprint(certDer));
return {
keys: [
{
alg: 'RS256',
e: Buffer.isBuffer(exponent) ? exponent.toString() : $2e261e4cdbe2c032$var$bnToB64(String(exponent)),
kid: thumbprint,
kty: 'RSA',
n: modulus.toString('base64'),
use: 'sig',
x5c: [
certDer
],
x5t: thumbprint
}
]
};
};
const $2e261e4cdbe2c032$export$dfe45055eb4a3f83 = ()=>{
const privateKey = (0, $bHgEm$nodeforge).pki.privateKeyFromPem($2e261e4cdbe2c032$var$PRIVATE_KEY_PEM);
const publicKey = (0, $bHgEm$nodeforge).pki.publicKeyFromPem($2e261e4cdbe2c032$var$PUBLIC_KEY_PEM);
return {
privateKey: privateKey,
publicKey: publicKey
};
};
const $2e261e4cdbe2c032$export$1d452baa218acb3 = (privateKey, jwtPayload, kid)=>(0, $bHgEm$jsonwebtoken).sign(jwtPayload, (0, $bHgEm$nodeforge).pki.privateKeyToPem(privateKey), {
header: {
kid: kid,
alg: 'RS256'
}
});
// Below taken from https://coolaj86.com/articles/bigints-and-base64-in-javascript/
// Binary string to ASCII (base64)
function $2e261e4cdbe2c032$var$btoa(bin) {
return Buffer.from(bin, 'binary').toString('base64');
}
function $2e261e4cdbe2c032$var$bnToB64(bn) {
let hex = BigInt(bn).toString(16);
if (hex.length % 2) hex = `0${hex}`;
const bin = [];
let i = 0;
let d;
let b;
while(i < hex.length){
d = Number.parseInt(hex.slice(i, i + 2), 16);
b = String.fromCharCode(d);
bin.push(b);
i += 2;
}
return $2e261e4cdbe2c032$var$btoa(bin.join(''));
}
const $4c4cb2c53d771b65$export$17c94918db2c5155 = (jwksBase, jwksPath = '/.well-known/jwks.json')=>{
const keypair = (0, $2e261e4cdbe2c032$export$dfe45055eb4a3f83)();
const JWKS = (0, $2e261e4cdbe2c032$export$ee715dcb214d41eb)({
...keypair,
jwksOrigin: jwksBase
});
const handler = (0, $bHgEm$http).get(new URL(jwksPath, jwksBase).href, ()=>(0, $bHgEm$HttpResponse).json(JWKS));
const kid = ()=>JWKS.keys[0].kid;
let server;
const stop = ()=>{
server?.close();
server = undefined;
};
const start = ()=>{
if (server) throw new Error('JWKSMock is already started');
server = (0, $bHgEm$setupServer)(handler);
server.listen({
onUnhandledRequest: 'bypass'
});
return ()=>stop();
};
const token = (token = {})=>(0, $2e261e4cdbe2c032$export$1d452baa218acb3)(keypair.privateKey, token, kid());
return {
start: start,
stop: /**
* @deprecated Use the thunk returned by `start` instead.
*/ stop,
kid: kid,
token: token,
mswHandler: handler
};
};
var /**
* @deprecated Use the named export instead
*/ $4c4cb2c53d771b65$export$2e2bcd8739ae039 = $4c4cb2c53d771b65$export$17c94918db2c5155;
export {$4c4cb2c53d771b65$export$17c94918db2c5155 as createJWKSMock, $4c4cb2c53d771b65$export$2e2bcd8739ae039 as default};
//# sourceMappingURL=module.js.map