Compare commits

..

8 Commits

4 changed files with 193 additions and 227 deletions
+41 -12
View File
@@ -15,6 +15,7 @@ let issuer = process.env.ISSUER || 'localhost:3333'
let jwksOrigin = `https://${issuer}/`
const audience = process.env.AUDIENCE || 'https://generic-audience'
const adminCustomClaim = process.env.ADMIN_CUSTOM_CLAIM || 'https://unbound.se/admin'
const emailCustomClaim = process.env.EMAIL_CUSTOM_CLAIM || 'https://unbound.se/email'
const debug = Debug('app')
@@ -27,10 +28,22 @@ const corsOpts = (req, cb) => {
cb(null, { origin: req.headers.origin })
}
const addCustomClaims = (email, customClaims, token) => {
const emailClaim = {}
emailClaim[emailCustomClaim] = email
return [...customClaims, emailClaim].reduce((acc, claim) => {
return {
...acc,
...claim
}
}, token)
}
// Configure our small auth0-mock-server
app.options('*', cors(corsOpts))
.use(cors())
.use(bodyParser.json())
.use(bodyParser.json({ strict: false }))
.use(bodyParser.urlencoded({ extended: true }))
.use(cookieParser())
.use(express.static(`${__dirname}/public`))
@@ -42,24 +55,19 @@ app.post('/oauth/token', (req, res) => {
const session = sessions[code]
let date = Math.floor(Date.now() / 1000)
let accessToken = jwt.sign(Buffer.from(JSON.stringify({
let accessToken = jwt.sign(Buffer.from(JSON.stringify(addCustomClaims(session.email, session.customClaims, {
iss: jwksOrigin,
aud: [audience],
sub: 'auth0|' + session.email,
iat: date,
exp: date + 7200,
azp: session.clientId
})), privateKey, {
}))), privateKey, {
algorithm: 'RS256',
keyid: thumbprint
})
const token = session.customClaims.reduce((acc, claim) => {
return {
...acc,
...claim
}
}, {
let idToken = jwt.sign(Buffer.from(JSON.stringify(addCustomClaims(session.email, session.customClaims, {
iss: jwksOrigin,
aud: session.clientId,
nonce: session.nonce,
@@ -69,8 +77,7 @@ app.post('/oauth/token', (req, res) => {
azp: session.clientId,
name: 'Example Person',
picture: 'https://cdn.playbuzz.com/cdn/5458360f-32ea-460e-a707-1a2d26760558/70bda687-cb84-4756-8a44-8cf735ed87b3.jpg'
})
let idToken = jwt.sign(Buffer.from(JSON.stringify(token)), privateKey, {
}))), privateKey, {
algorithm: 'RS256',
keyid: thumbprint
})
@@ -257,7 +264,7 @@ app.post('/issuer', (req, res) => {
}
issuer = req.body.issuer
jwksOrigin = `https://${issuer}/`
const { privateKey: key, certDer: der, thumbPrint: thumb, exponent: exp, modulus: mod } = cert(jwksOrigin)
const { privateKey: key, certDer: der, thumbprint: thumb, exponent: exp, modulus: mod } = cert(jwksOrigin)
privateKey = key
certDer = der
thumbprint = thumb
@@ -267,6 +274,28 @@ app.post('/issuer', (req, res) => {
res.send('ok')
})
app.get('/api/v2/users-by-email', (req, res) => {
res.json([])
})
app.post('/api/v2/users', (req, res) => {
const email = req.body.email
res.json({
user_id: `auth0|${email}`
})
})
app.post('/api/v2/tickets/password-change', (req, res) => {
res.json({
ticket: `https://some-url`
})
})
app.use(function(req, res, next) {
console.log('404', req.path)
res.status(404).send('error: 404 Not Found ' + req.path)
})
app.listen(3333, () => {
debug('Auth0-Mock-Server listening on port 3333!')
})
+112 -112
View File
@@ -1,132 +1,132 @@
const base64url = require('base64-url');
const createHash = require('crypto').createHash;
const forge = require('node-forge');
const NodeRSA = require('node-rsa');
const base64url = require('base64-url')
const createHash = require('crypto').createHash
const forge = require('node-forge')
const NodeRSA = require('node-rsa')
const PRIVATE_KEY_PEM =
'-----BEGIN RSA PRIVATE KEY-----\n' +
'MIIEpAIBAAKCAQEApoocpO3bbUF6o8eyJlQCfwLahEsunWdVF++yOEyKu4Lp1j0m\n' +
'2j/P7iHOtxBAkjdM2X2oW3qO1mR0sIFefqnm93g0q2nRuYEoS+W3o6X50wjOVm8f\n' +
'r/tLqELzy5BoET0AQl7Axp1DNsb0HNOBcoIBt+xVY4I+k6uXJJJMzbgvahAgSLZ9\n' +
'RW0Z0WT+dCHZpZUj0nLxNXIPdci65Bw6IognqXHP6AwKZXpT6jCzjzq9uyHxVcud\n' +
'qw6j0kQw48/A5A6AN5fIVy1cKnd0sKdqRX1NUqVoiOrO4jaDB1IdLD+YmRE/JjOH\n' +
'sWIMElYCPxKqnsNo6VCslGX/ziinArHhqRBrHwIDAQABAoIBAHAdmpsN5iLvafjI\n' +
'f45+EBAhg6p8Uq102zx6CakNHniN8Y5hLL7RJtJRwDBNqKrGv93LUoQDRhXfGw+Y\n' +
'iF0NVIhVTF/5pU8VPGOcCr0JB96ilwZpWRPIQW7NZAMu/GBeiMYls/IB/TXrSnv9\n' +
'h6/nBfEkEXgkPqx7YA0m0L3NuV3U1lCY/LhBJY4Xvi0uRdqu3tTHXftehuPwC4UB\n' +
'42eJTWv/qLeOlkCdUUV4f7+dNaES88Vdhj6lu/BusnNhvnwHQik4dNwzPCGeP8NV\n' +
'5gaesWiNWFZuTURGKk1B65p5LzNPjsVT50RDuW8FnSZwIvNcohrX9ILPsmg/t0Kr\n' +
'ozcOksECgYEA4XWOK4twx5RG162zveRHqU7H9RBWSz7/PzM9Eob9vx/tC/b1YqBR\n' +
'VShk23vje19eNiYWAkxcpobIP4ek/0ZT8nHkJg8wl+J/hnXADcvwv2dKnoFnm5pn\n' +
'rTBUKc8R3wrSlAV8XQAtdnxsfFa5AOQJ6WFVI9AdfH3Iw8XZk4gIIPMCgYEAvRlY\n' +
'y80HnR3kwMOqY488V1qk41dmfNqa+YDL+zkPF1HhHI9VnK5BQuI7lyKJl984KwHu\n' +
'0gbwx3Wp4XkD5JUboEpl5LnaLsjEWemjTaQWdvJHPd5wkJ0m/jRQ2YeT4g2gFu4y\n' +
'Pi/pWkrzhnzQQVAmOdAm5Kj27LtDzp0lspw3uCUCgYEAw2YdvFGSgfZZW4147QeO\n' +
'sAbON+9bysUjdMPUl10VR/LEgA0d6MdnFfX3S13Y7tDdlvJ1OrKxzcWcgaru7ism\n' +
'kEXy5KVfiRNNUNx2gb6RvWEpA6zFfc9ZMXlkSAPlyjfX/1+tw/Bmdn0pjK2gk0wP\n' +
'5wtrPameFInzWPD9O+a2nM8CgYBZ6UhgNs+M9B7FTQOiLQPa4R2PfwobCXIwef4D\n' +
'KIE1bFgl1T02r2AWZi1BUkmr7ZXuVQ/xyx0HKbopm/mu4PruvxEtrPTB0/IQcleU\n' +
'XhXUXqRjFXXePOrCaaubkqxNCn95B67aBLvmk8awxn3a4DocuQ0VIgWuT+gQwIWh\n' +
'JEgWBQKBgQDKD+2Yh1/rUzu15lbPH0JSpozUinuFjePieR/4n+5CtEUxWJ2f0WeK\n' +
's4XWWf2qgUccjpiGju2UR840mgWROoZ8BfSTd5tg1F7bo0HMgu2hu0RIRpZcRhsA\n' +
'Cd0GrJvf1t0QIdDCXAy+RpgU1SLSq4Q6Lomc0WA5C5nBw9RKEUOV9A==\n' +
'-----END RSA PRIVATE KEY-----\n';
'-----BEGIN RSA PRIVATE KEY-----\n' +
'MIIEpAIBAAKCAQEApoocpO3bbUF6o8eyJlQCfwLahEsunWdVF++yOEyKu4Lp1j0m\n' +
'2j/P7iHOtxBAkjdM2X2oW3qO1mR0sIFefqnm93g0q2nRuYEoS+W3o6X50wjOVm8f\n' +
'r/tLqELzy5BoET0AQl7Axp1DNsb0HNOBcoIBt+xVY4I+k6uXJJJMzbgvahAgSLZ9\n' +
'RW0Z0WT+dCHZpZUj0nLxNXIPdci65Bw6IognqXHP6AwKZXpT6jCzjzq9uyHxVcud\n' +
'qw6j0kQw48/A5A6AN5fIVy1cKnd0sKdqRX1NUqVoiOrO4jaDB1IdLD+YmRE/JjOH\n' +
'sWIMElYCPxKqnsNo6VCslGX/ziinArHhqRBrHwIDAQABAoIBAHAdmpsN5iLvafjI\n' +
'f45+EBAhg6p8Uq102zx6CakNHniN8Y5hLL7RJtJRwDBNqKrGv93LUoQDRhXfGw+Y\n' +
'iF0NVIhVTF/5pU8VPGOcCr0JB96ilwZpWRPIQW7NZAMu/GBeiMYls/IB/TXrSnv9\n' +
'h6/nBfEkEXgkPqx7YA0m0L3NuV3U1lCY/LhBJY4Xvi0uRdqu3tTHXftehuPwC4UB\n' +
'42eJTWv/qLeOlkCdUUV4f7+dNaES88Vdhj6lu/BusnNhvnwHQik4dNwzPCGeP8NV\n' +
'5gaesWiNWFZuTURGKk1B65p5LzNPjsVT50RDuW8FnSZwIvNcohrX9ILPsmg/t0Kr\n' +
'ozcOksECgYEA4XWOK4twx5RG162zveRHqU7H9RBWSz7/PzM9Eob9vx/tC/b1YqBR\n' +
'VShk23vje19eNiYWAkxcpobIP4ek/0ZT8nHkJg8wl+J/hnXADcvwv2dKnoFnm5pn\n' +
'rTBUKc8R3wrSlAV8XQAtdnxsfFa5AOQJ6WFVI9AdfH3Iw8XZk4gIIPMCgYEAvRlY\n' +
'y80HnR3kwMOqY488V1qk41dmfNqa+YDL+zkPF1HhHI9VnK5BQuI7lyKJl984KwHu\n' +
'0gbwx3Wp4XkD5JUboEpl5LnaLsjEWemjTaQWdvJHPd5wkJ0m/jRQ2YeT4g2gFu4y\n' +
'Pi/pWkrzhnzQQVAmOdAm5Kj27LtDzp0lspw3uCUCgYEAw2YdvFGSgfZZW4147QeO\n' +
'sAbON+9bysUjdMPUl10VR/LEgA0d6MdnFfX3S13Y7tDdlvJ1OrKxzcWcgaru7ism\n' +
'kEXy5KVfiRNNUNx2gb6RvWEpA6zFfc9ZMXlkSAPlyjfX/1+tw/Bmdn0pjK2gk0wP\n' +
'5wtrPameFInzWPD9O+a2nM8CgYBZ6UhgNs+M9B7FTQOiLQPa4R2PfwobCXIwef4D\n' +
'KIE1bFgl1T02r2AWZi1BUkmr7ZXuVQ/xyx0HKbopm/mu4PruvxEtrPTB0/IQcleU\n' +
'XhXUXqRjFXXePOrCaaubkqxNCn95B67aBLvmk8awxn3a4DocuQ0VIgWuT+gQwIWh\n' +
'JEgWBQKBgQDKD+2Yh1/rUzu15lbPH0JSpozUinuFjePieR/4n+5CtEUxWJ2f0WeK\n' +
's4XWWf2qgUccjpiGju2UR840mgWROoZ8BfSTd5tg1F7bo0HMgu2hu0RIRpZcRhsA\n' +
'Cd0GrJvf1t0QIdDCXAy+RpgU1SLSq4Q6Lomc0WA5C5nBw9RKEUOV9A==\n' +
'-----END RSA PRIVATE KEY-----\n'
const PUBLIC_KEY_PEM =
'-----BEGIN PUBLIC KEY-----\n' +
'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApoocpO3bbUF6o8eyJlQC\n' +
'fwLahEsunWdVF++yOEyKu4Lp1j0m2j/P7iHOtxBAkjdM2X2oW3qO1mR0sIFefqnm\n' +
'93g0q2nRuYEoS+W3o6X50wjOVm8fr/tLqELzy5BoET0AQl7Axp1DNsb0HNOBcoIB\n' +
't+xVY4I+k6uXJJJMzbgvahAgSLZ9RW0Z0WT+dCHZpZUj0nLxNXIPdci65Bw6Iogn\n' +
'qXHP6AwKZXpT6jCzjzq9uyHxVcudqw6j0kQw48/A5A6AN5fIVy1cKnd0sKdqRX1N\n' +
'UqVoiOrO4jaDB1IdLD+YmRE/JjOHsWIMElYCPxKqnsNo6VCslGX/ziinArHhqRBr\n' +
'HwIDAQAB\n' +
'-----END PUBLIC KEY-----\n';
'-----BEGIN PUBLIC KEY-----\n' +
'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApoocpO3bbUF6o8eyJlQC\n' +
'fwLahEsunWdVF++yOEyKu4Lp1j0m2j/P7iHOtxBAkjdM2X2oW3qO1mR0sIFefqnm\n' +
'93g0q2nRuYEoS+W3o6X50wjOVm8fr/tLqELzy5BoET0AQl7Axp1DNsb0HNOBcoIB\n' +
't+xVY4I+k6uXJJJMzbgvahAgSLZ9RW0Z0WT+dCHZpZUj0nLxNXIPdci65Bw6Iogn\n' +
'qXHP6AwKZXpT6jCzjzq9uyHxVcudqw6j0kQw48/A5A6AN5fIVy1cKnd0sKdqRX1N\n' +
'UqVoiOrO4jaDB1IdLD+YmRE/JjOHsWIMElYCPxKqnsNo6VCslGX/ziinArHhqRBr\n' +
'HwIDAQAB\n' +
'-----END PUBLIC KEY-----\n'
const createCertificate = ({
publicKey,
privateKey,
jwksOrigin,
publicKey,
privateKey,
jwksOrigin
}) => {
const cert = forge.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.setIssuer(attrs);
cert.sign(privateKey);
return forge.pki.certificateToPem(cert)
};
const cert = forge.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.setIssuer(attrs)
cert.sign(privateKey)
return forge.pki.certificateToPem(cert)
}
const getCertThumbprint = (certificate) => {
const shasum = createHash('sha1');
const der = Buffer.from(certificate).toString('binary');
shasum.update(der);
return shasum.digest('base64')
};
const shasum = createHash('sha1')
const der = Buffer.from(certificate).toString('binary')
shasum.update(der)
return shasum.digest('base64')
}
const createKeyPair = () => {
const privateKey = forge.pki.privateKeyFromPem(PRIVATE_KEY_PEM);
const publicKey = forge.pki.publicKeyFromPem(PUBLIC_KEY_PEM);
return {
privateKey,
publicKey,
}
};
const privateKey = forge.pki.privateKeyFromPem(PRIVATE_KEY_PEM)
const publicKey = forge.pki.publicKeyFromPem(PUBLIC_KEY_PEM)
return {
privateKey,
publicKey
}
}
const bnToB64 = (bn) => {
let hex = BigInt(bn).toString(16);
if (hex.length % 2) {
hex = '0' + hex;
}
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 = parseInt(hex.slice(i, i + 2), 16);
b = String.fromCharCode(d);
bin.push(b);
i += 2;
}
const bin = []
let i = 0
let d
let b
while (i < hex.length) {
d = parseInt(hex.slice(i, i + 2), 16)
b = String.fromCharCode(d)
bin.push(b)
i += 2
}
return Buffer.from(bin.join(''), 'binary').toString('base64');
};
return Buffer.from(bin.join(''), 'binary').toString('base64')
}
const setup = (jwksOrigin) => {
const {privateKey, publicKey} = createKeyPair();
const certPem = createCertificate({
jwksOrigin,
privateKey,
publicKey,
});
const certDer = forge.util.encode64(
forge.asn1
.toDer(forge.pki.certificateToAsn1(forge.pki.certificateFromPem(certPem)))
.getBytes()
);
const thumbprint = base64url.encode(getCertThumbprint(certDer));
const { privateKey, publicKey } = createKeyPair()
const certPem = createCertificate({
jwksOrigin,
privateKey,
publicKey
})
const certDer = forge.util.encode64(
forge.asn1
.toDer(forge.pki.certificateToAsn1(forge.pki.certificateFromPem(certPem)))
.getBytes()
)
const thumbprint = base64url.encode(getCertThumbprint(certDer))
const helperKey = new NodeRSA();
helperKey.importKey(forge.pki.privateKeyToPem(privateKey));
const {n: modulus, e: exponent} = helperKey.exportKey('components');
const helperKey = new NodeRSA()
helperKey.importKey(forge.pki.privateKeyToPem(privateKey))
const { n: modulus, e: exponent } = helperKey.exportKey('components')
return {
privateKey: forge.pki.privateKeyToPem(privateKey),
certDer: certDer,
thumbPrint: thumbprint,
exponent: bnToB64(exponent),
modulus: modulus.toString('base64')
}
};
return {
privateKey: forge.pki.privateKeyToPem(privateKey),
certDer,
thumbprint: thumbprint.toString(),
exponent: bnToB64(exponent),
modulus: modulus.toString('base64')
}
}
module.exports = setup;
module.exports = setup
+1 -1
View File
@@ -17,7 +17,7 @@
"cookie-parser": "^1.4.6",
"cors": "^2.8.3",
"debug": "^4.3.4",
"express": "^4.17.3",
"express": "^4.18.0",
"https-localhost": "^4.7.1",
"jsonwebtoken": "^8.5.1",
"node-forge": "^1.3.1",
+39 -102
View File
@@ -114,23 +114,7 @@ binary-extensions@^2.0.0:
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c"
integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==
body-parser@1.19.2:
version "1.19.2"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.2.tgz#4714ccd9c157d44797b8b5607d72c0b89952f26e"
integrity sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==
dependencies:
bytes "3.1.2"
content-type "~1.0.4"
debug "2.6.9"
depd "~1.1.2"
http-errors "1.8.1"
iconv-lite "0.4.24"
on-finished "~2.3.0"
qs "6.9.7"
raw-body "2.4.3"
type-is "~1.6.18"
body-parser@^1.20.0:
body-parser@1.20.0, body-parser@^1.20.0:
version "1.20.0"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5"
integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==
@@ -345,10 +329,10 @@ cookie@0.4.1:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1"
integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==
cookie@0.4.2:
version "0.4.2"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432"
integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==
cookie@0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
core-util-is@~1.0.0:
version "1.0.2"
@@ -411,21 +395,11 @@ depd@2.0.0:
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
depd@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
destroy@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
destroy@~1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
detect-node@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c"
@@ -492,38 +466,39 @@ etag@~1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
express@^4.17.1, express@^4.17.3:
version "4.17.3"
resolved "https://registry.yarnpkg.com/express/-/express-4.17.3.tgz#f6c7302194a4fb54271b73a1fe7a06478c8f85a1"
integrity sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==
express@^4.17.1, express@^4.18.0:
version "4.18.0"
resolved "https://registry.yarnpkg.com/express/-/express-4.18.0.tgz#7a426773325d0dd5406395220614c0db10b6e8e2"
integrity sha512-EJEXxiTQJS3lIPrU1AE2vRuT7X7E+0KBbpm5GSoK524yl0K8X+er8zS2P14E64eqsVNoWbMCT7MpmQ+ErAhgRg==
dependencies:
accepts "~1.3.8"
array-flatten "1.1.1"
body-parser "1.19.2"
body-parser "1.20.0"
content-disposition "0.5.4"
content-type "~1.0.4"
cookie "0.4.2"
cookie "0.5.0"
cookie-signature "1.0.6"
debug "2.6.9"
depd "~1.1.2"
depd "2.0.0"
encodeurl "~1.0.2"
escape-html "~1.0.3"
etag "~1.8.1"
finalhandler "~1.1.2"
finalhandler "1.2.0"
fresh "0.5.2"
http-errors "2.0.0"
merge-descriptors "1.0.1"
methods "~1.1.2"
on-finished "~2.3.0"
on-finished "2.4.1"
parseurl "~1.3.3"
path-to-regexp "0.1.7"
proxy-addr "~2.0.7"
qs "6.9.7"
qs "6.10.3"
range-parser "~1.2.1"
safe-buffer "5.2.1"
send "0.17.2"
serve-static "1.14.2"
send "0.18.0"
serve-static "1.15.0"
setprototypeof "1.2.0"
statuses "~1.5.0"
statuses "2.0.1"
type-is "~1.6.18"
utils-merge "1.0.1"
vary "~1.1.2"
@@ -535,17 +510,17 @@ fill-range@^7.0.1:
dependencies:
to-regex-range "^5.0.1"
finalhandler@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d"
integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==
finalhandler@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32"
integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==
dependencies:
debug "2.6.9"
encodeurl "~1.0.2"
escape-html "~1.0.3"
on-finished "~2.3.0"
on-finished "2.4.1"
parseurl "~1.3.3"
statuses "~1.5.0"
statuses "2.0.1"
unpipe "~1.0.0"
forwarded@0.2.0:
@@ -679,17 +654,6 @@ http-deceiver@^1.2.7:
resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=
http-errors@1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c"
integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==
dependencies:
depd "~1.1.2"
inherits "2.0.4"
setprototypeof "1.2.0"
statuses ">= 1.5.0 < 2"
toidentifier "1.0.1"
http-errors@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
@@ -1113,13 +1077,6 @@ on-finished@2.4.1:
dependencies:
ee-first "1.1.1"
on-finished@~2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=
dependencies:
ee-first "1.1.1"
on-headers@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f"
@@ -1212,26 +1169,11 @@ qs@6.10.3:
dependencies:
side-channel "^1.0.4"
qs@6.9.7:
version "6.9.7"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.7.tgz#4610846871485e1e048f44ae3b94033f0e675afe"
integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==
range-parser@~1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
raw-body@2.4.3:
version "2.4.3"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.3.tgz#8f80305d11c2a0a545c2d9d89d7a0286fcead43c"
integrity sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==
dependencies:
bytes "3.1.2"
http-errors "1.8.1"
iconv-lite "0.4.24"
unpipe "1.0.0"
raw-body@2.5.1:
version "2.5.1"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857"
@@ -1351,24 +1293,24 @@ semver@^7.3.4:
dependencies:
lru-cache "^6.0.0"
send@0.17.2:
version "0.17.2"
resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820"
integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==
send@0.18.0:
version "0.18.0"
resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"
integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==
dependencies:
debug "2.6.9"
depd "~1.1.2"
destroy "~1.0.4"
depd "2.0.0"
destroy "1.2.0"
encodeurl "~1.0.2"
escape-html "~1.0.3"
etag "~1.8.1"
fresh "0.5.2"
http-errors "1.8.1"
http-errors "2.0.0"
mime "1.6.0"
ms "2.1.3"
on-finished "~2.3.0"
on-finished "2.4.1"
range-parser "~1.2.1"
statuses "~1.5.0"
statuses "2.0.1"
serve-favicon@^2.4.2:
version "2.5.0"
@@ -1381,15 +1323,15 @@ serve-favicon@^2.4.2:
parseurl "~1.3.2"
safe-buffer "5.1.1"
serve-static@1.14.2:
version "1.14.2"
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa"
integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==
serve-static@1.15.0:
version "1.15.0"
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540"
integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==
dependencies:
encodeurl "~1.0.2"
escape-html "~1.0.3"
parseurl "~1.3.3"
send "0.17.2"
send "0.18.0"
setprototypeof@1.2.0:
version "1.2.0"
@@ -1438,11 +1380,6 @@ statuses@2.0.1:
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
"statuses@>= 1.5.0 < 2", statuses@~1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
string-width@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"