Compare commits

...

12 Commits

Author SHA1 Message Date
argoyle b4d5dbe9e3 feat: add dummy-implementation of management API 2022-04-26 16:54:03 +02:00
argoyle b476cf0e36 fix: use correct return-variable 2022-04-26 15:37:19 +02:00
argoyle 37ac46759d fix: make sure thumbPrint is a string 2022-04-26 15:22:53 +02:00
argoyle 424e500d6b chore: format code 2022-04-26 15:22:39 +02:00
argoyle 9539d9b38d Merge branch 'dependabot-npm_and_yarn-express-4.18.0' into 'main'
Chore(deps): bump express from 4.17.3 to 4.18.0

See merge request unboundsoftware/auth0mock!35
2022-04-26 11:01:52 +00:00
argoyle a9ea2dace4 fix: add custom claims to both id and access token 2022-04-26 11:49:19 +02:00
argoyle aad18ad000 feat: add email custom claim 2022-04-26 11:08:19 +02:00
argoyle b009965908 feat: add env-property for default issuer 2022-04-26 09:55:56 +02:00
argoyle 68d3f0df82 Chore(deps): bump express from 4.17.3 to 4.18.0
Bumps [express](https://github.com/expressjs/express) from 4.17.3 to 4.18.0.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.17.3...4.18.0)
2022-04-26 06:52:17 +00:00
argoyle cc1b28f81f chore: change admin-handling 2022-04-25 21:26:01 +02:00
argoyle 99a55a45e3 Merge branch 'dependabot-docker-node-18' into 'main'
Chore(deps): bump node from 17 to 18

See merge request unboundsoftware/auth0mock!34
2022-04-21 06:04:31 +00:00
argoyle 7b6ff1fa0e Chore(deps): bump node from 17 to 18
Bumps node from 17 to 18.
2022-04-21 06:00:42 +00:00
5 changed files with 200 additions and 231 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
FROM node:17 FROM node:18
ENV AUDIENCE "https://shiny.unbound.se" ENV AUDIENCE "https://shiny.unbound.se"
ENV ORIGIN_HOST "auth0mock" ENV ORIGIN_HOST "auth0mock"
ENV ORIGIN "https://auth0mock:3333" ENV ORIGIN "https://auth0mock:3333"
+47 -15
View File
@@ -11,10 +11,11 @@ const bodyParser = require('body-parser')
const favicon = require('serve-favicon') const favicon = require('serve-favicon')
const cert = require('./cert') const cert = require('./cert')
let issuer = 'localhost:3333' let issuer = process.env.ISSUER || 'localhost:3333'
let jwksOrigin = `https://${issuer}/` let jwksOrigin = `https://${issuer}/`
const audience = process.env.AUDIENCE || 'https://generic-audience' const audience = process.env.AUDIENCE || 'https://generic-audience'
const adminRole = process.env.ADMIN_ROLE || 'admin' 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') const debug = Debug('app')
@@ -27,10 +28,22 @@ const corsOpts = (req, cb) => {
cb(null, { origin: req.headers.origin }) 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 // Configure our small auth0-mock-server
app.options('*', cors(corsOpts)) app.options('*', cors(corsOpts))
.use(cors()) .use(cors())
.use(bodyParser.json()) .use(bodyParser.json({ strict: false }))
.use(bodyParser.urlencoded({ extended: true })) .use(bodyParser.urlencoded({ extended: true }))
.use(cookieParser()) .use(cookieParser())
.use(express.static(`${__dirname}/public`)) .use(express.static(`${__dirname}/public`))
@@ -42,19 +55,19 @@ app.post('/oauth/token', (req, res) => {
const session = sessions[code] const session = sessions[code]
let date = Math.floor(Date.now() / 1000) 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, iss: jwksOrigin,
aud: [audience], aud: [audience],
sub: 'auth0|' + session.email, sub: 'auth0|' + session.email,
iat: date, iat: date,
exp: date + 7200, exp: date + 7200,
azp: session.clientId azp: session.clientId
})), privateKey, { }))), privateKey, {
algorithm: 'RS256', algorithm: 'RS256',
keyid: thumbprint keyid: thumbprint
}) })
let idToken = jwt.sign(Buffer.from(JSON.stringify({ let idToken = jwt.sign(Buffer.from(JSON.stringify(addCustomClaims(session.email, session.customClaims, {
iss: jwksOrigin, iss: jwksOrigin,
aud: session.clientId, aud: session.clientId,
nonce: session.nonce, nonce: session.nonce,
@@ -63,9 +76,8 @@ app.post('/oauth/token', (req, res) => {
exp: date + 7200, exp: date + 7200,
azp: session.clientId, azp: session.clientId,
name: 'Example Person', name: 'Example Person',
picture: 'https://cdn.playbuzz.com/cdn/5458360f-32ea-460e-a707-1a2d26760558/70bda687-cb84-4756-8a44-8cf735ed87b3.jpg', picture: 'https://cdn.playbuzz.com/cdn/5458360f-32ea-460e-a707-1a2d26760558/70bda687-cb84-4756-8a44-8cf735ed87b3.jpg'
'https://unbound.se/roles': session.roles }))), privateKey, {
})), privateKey, {
algorithm: 'RS256', algorithm: 'RS256',
keyid: thumbprint keyid: thumbprint
}) })
@@ -104,10 +116,8 @@ app.post('/code', (req, res) => {
const code = req.body.codeChallenge const code = req.body.codeChallenge
challenges[req.body.codeChallenge] = code challenges[req.body.codeChallenge] = code
const state = req.body.state const state = req.body.state
let roles = [] const claim = {}
if (req.body.admin === 'true') { claim[adminCustomClaim] = req.body.admin === 'true'
roles = [adminRole]
}
sessions[code] = { sessions[code] = {
email: req.body.email, email: req.body.email,
password: req.body.password, password: req.body.password,
@@ -115,7 +125,7 @@ app.post('/code', (req, res) => {
nonce: req.body.nonce, nonce: req.body.nonce,
clientId: req.body.clientId, clientId: req.body.clientId,
codeChallenge: req.body.codeChallenge, codeChallenge: req.body.codeChallenge,
roles: roles customClaims: [claim]
} }
res.redirect(`${req.body.redirect}?domain=${issuer}&code=${code}&state=${encodeURIComponent(state)}`) res.redirect(`${req.body.redirect}?domain=${issuer}&code=${code}&state=${encodeURIComponent(state)}`)
}) })
@@ -254,7 +264,7 @@ app.post('/issuer', (req, res) => {
} }
issuer = req.body.issuer issuer = req.body.issuer
jwksOrigin = `https://${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 privateKey = key
certDer = der certDer = der
thumbprint = thumb thumbprint = thumb
@@ -264,6 +274,28 @@ app.post('/issuer', (req, res) => {
res.send('ok') 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, () => { app.listen(3333, () => {
debug('Auth0-Mock-Server listening on port 3333!') debug('Auth0-Mock-Server listening on port 3333!')
}) })
+112 -112
View File
@@ -1,132 +1,132 @@
const base64url = require('base64-url'); const base64url = require('base64-url')
const createHash = require('crypto').createHash; const createHash = require('crypto').createHash
const forge = require('node-forge'); const forge = require('node-forge')
const NodeRSA = require('node-rsa'); const NodeRSA = require('node-rsa')
const PRIVATE_KEY_PEM = const PRIVATE_KEY_PEM =
'-----BEGIN RSA PRIVATE KEY-----\n' + '-----BEGIN RSA PRIVATE KEY-----\n' +
'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\n' +
'-----END RSA PRIVATE KEY-----\n'; '-----END RSA PRIVATE KEY-----\n'
const PUBLIC_KEY_PEM = const PUBLIC_KEY_PEM =
'-----BEGIN PUBLIC KEY-----\n' + '-----BEGIN PUBLIC KEY-----\n' +
'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApoocpO3bbUF6o8eyJlQC\n' + 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApoocpO3bbUF6o8eyJlQC\n' +
'fwLahEsunWdVF++yOEyKu4Lp1j0m2j/P7iHOtxBAkjdM2X2oW3qO1mR0sIFefqnm\n' + 'fwLahEsunWdVF++yOEyKu4Lp1j0m2j/P7iHOtxBAkjdM2X2oW3qO1mR0sIFefqnm\n' +
'93g0q2nRuYEoS+W3o6X50wjOVm8fr/tLqELzy5BoET0AQl7Axp1DNsb0HNOBcoIB\n' + '93g0q2nRuYEoS+W3o6X50wjOVm8fr/tLqELzy5BoET0AQl7Axp1DNsb0HNOBcoIB\n' +
't+xVY4I+k6uXJJJMzbgvahAgSLZ9RW0Z0WT+dCHZpZUj0nLxNXIPdci65Bw6Iogn\n' + 't+xVY4I+k6uXJJJMzbgvahAgSLZ9RW0Z0WT+dCHZpZUj0nLxNXIPdci65Bw6Iogn\n' +
'qXHP6AwKZXpT6jCzjzq9uyHxVcudqw6j0kQw48/A5A6AN5fIVy1cKnd0sKdqRX1N\n' + 'qXHP6AwKZXpT6jCzjzq9uyHxVcudqw6j0kQw48/A5A6AN5fIVy1cKnd0sKdqRX1N\n' +
'UqVoiOrO4jaDB1IdLD+YmRE/JjOHsWIMElYCPxKqnsNo6VCslGX/ziinArHhqRBr\n' + 'UqVoiOrO4jaDB1IdLD+YmRE/JjOHsWIMElYCPxKqnsNo6VCslGX/ziinArHhqRBr\n' +
'HwIDAQAB\n' + 'HwIDAQAB\n' +
'-----END PUBLIC KEY-----\n'; '-----END PUBLIC KEY-----\n'
const createCertificate = ({ const createCertificate = ({
publicKey, publicKey,
privateKey, privateKey,
jwksOrigin, jwksOrigin
}) => { }) => {
const cert = forge.pki.createCertificate(); const cert = forge.pki.createCertificate()
cert.publicKey = publicKey; cert.publicKey = publicKey
cert.serialNumber = '123'; cert.serialNumber = '123'
const attrs = [ const attrs = [
{ {
name: 'commonName', name: 'commonName',
value: `${jwksOrigin}`, value: `${jwksOrigin}`
}, }
]; ]
cert.validity.notBefore = new Date(); cert.validity.notBefore = new Date()
cert.validity.notAfter = new Date(); cert.validity.notAfter = new Date()
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1); cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1)
cert.setSubject(attrs); cert.setSubject(attrs)
cert.setIssuer(attrs); cert.setIssuer(attrs)
cert.sign(privateKey); cert.sign(privateKey)
return forge.pki.certificateToPem(cert) return forge.pki.certificateToPem(cert)
}; }
const getCertThumbprint = (certificate) => { const getCertThumbprint = (certificate) => {
const shasum = createHash('sha1'); const shasum = createHash('sha1')
const der = Buffer.from(certificate).toString('binary'); const der = Buffer.from(certificate).toString('binary')
shasum.update(der); shasum.update(der)
return shasum.digest('base64') return shasum.digest('base64')
}; }
const createKeyPair = () => { const createKeyPair = () => {
const privateKey = forge.pki.privateKeyFromPem(PRIVATE_KEY_PEM); const privateKey = forge.pki.privateKeyFromPem(PRIVATE_KEY_PEM)
const publicKey = forge.pki.publicKeyFromPem(PUBLIC_KEY_PEM); const publicKey = forge.pki.publicKeyFromPem(PUBLIC_KEY_PEM)
return { return {
privateKey, privateKey,
publicKey, publicKey
} }
}; }
const bnToB64 = (bn) => { const bnToB64 = (bn) => {
let hex = BigInt(bn).toString(16); let hex = BigInt(bn).toString(16)
if (hex.length % 2) { if (hex.length % 2) {
hex = '0' + hex; hex = '0' + hex
} }
const bin = []; const bin = []
let i = 0; let i = 0
let d; let d
let b; let b
while (i < hex.length) { while (i < hex.length) {
d = parseInt(hex.slice(i, i + 2), 16); d = parseInt(hex.slice(i, i + 2), 16)
b = String.fromCharCode(d); b = String.fromCharCode(d)
bin.push(b); bin.push(b)
i += 2; i += 2
} }
return Buffer.from(bin.join(''), 'binary').toString('base64'); return Buffer.from(bin.join(''), 'binary').toString('base64')
}; }
const setup = (jwksOrigin) => { const setup = (jwksOrigin) => {
const {privateKey, publicKey} = createKeyPair(); const { privateKey, publicKey } = createKeyPair()
const certPem = createCertificate({ const certPem = createCertificate({
jwksOrigin, jwksOrigin,
privateKey, privateKey,
publicKey, publicKey
}); })
const certDer = forge.util.encode64( const certDer = forge.util.encode64(
forge.asn1 forge.asn1
.toDer(forge.pki.certificateToAsn1(forge.pki.certificateFromPem(certPem))) .toDer(forge.pki.certificateToAsn1(forge.pki.certificateFromPem(certPem)))
.getBytes() .getBytes()
); )
const thumbprint = base64url.encode(getCertThumbprint(certDer)); const thumbprint = base64url.encode(getCertThumbprint(certDer))
const helperKey = new NodeRSA(); const helperKey = new NodeRSA()
helperKey.importKey(forge.pki.privateKeyToPem(privateKey)); helperKey.importKey(forge.pki.privateKeyToPem(privateKey))
const {n: modulus, e: exponent} = helperKey.exportKey('components'); const { n: modulus, e: exponent } = helperKey.exportKey('components')
return { return {
privateKey: forge.pki.privateKeyToPem(privateKey), privateKey: forge.pki.privateKeyToPem(privateKey),
certDer: certDer, certDer,
thumbPrint: thumbprint, thumbprint: thumbprint.toString(),
exponent: bnToB64(exponent), exponent: bnToB64(exponent),
modulus: modulus.toString('base64') modulus: modulus.toString('base64')
} }
}; }
module.exports = setup; module.exports = setup
+1 -1
View File
@@ -17,7 +17,7 @@
"cookie-parser": "^1.4.6", "cookie-parser": "^1.4.6",
"cors": "^2.8.3", "cors": "^2.8.3",
"debug": "^4.3.4", "debug": "^4.3.4",
"express": "^4.17.3", "express": "^4.18.0",
"https-localhost": "^4.7.1", "https-localhost": "^4.7.1",
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^8.5.1",
"node-forge": "^1.3.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" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c"
integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow== integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==
body-parser@1.19.2: body-parser@1.20.0, body-parser@^1.20.0:
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:
version "1.20.0" version "1.20.0"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" 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== 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" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1"
integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==
cookie@0.4.2: cookie@0.5.0:
version "0.4.2" version "0.5.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
core-util-is@~1.0.0: core-util-is@~1.0.0:
version "1.0.2" version "1.0.2"
@@ -411,21 +395,11 @@ depd@2.0.0:
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== 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: destroy@1.2.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== 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: detect-node@^2.0.4:
version "2.0.4" version "2.0.4"
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" 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" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
express@^4.17.1, express@^4.17.3: express@^4.17.1, express@^4.18.0:
version "4.17.3" version "4.18.0"
resolved "https://registry.yarnpkg.com/express/-/express-4.17.3.tgz#f6c7302194a4fb54271b73a1fe7a06478c8f85a1" resolved "https://registry.yarnpkg.com/express/-/express-4.18.0.tgz#7a426773325d0dd5406395220614c0db10b6e8e2"
integrity sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg== integrity sha512-EJEXxiTQJS3lIPrU1AE2vRuT7X7E+0KBbpm5GSoK524yl0K8X+er8zS2P14E64eqsVNoWbMCT7MpmQ+ErAhgRg==
dependencies: dependencies:
accepts "~1.3.8" accepts "~1.3.8"
array-flatten "1.1.1" array-flatten "1.1.1"
body-parser "1.19.2" body-parser "1.20.0"
content-disposition "0.5.4" content-disposition "0.5.4"
content-type "~1.0.4" content-type "~1.0.4"
cookie "0.4.2" cookie "0.5.0"
cookie-signature "1.0.6" cookie-signature "1.0.6"
debug "2.6.9" debug "2.6.9"
depd "~1.1.2" depd "2.0.0"
encodeurl "~1.0.2" encodeurl "~1.0.2"
escape-html "~1.0.3" escape-html "~1.0.3"
etag "~1.8.1" etag "~1.8.1"
finalhandler "~1.1.2" finalhandler "1.2.0"
fresh "0.5.2" fresh "0.5.2"
http-errors "2.0.0"
merge-descriptors "1.0.1" merge-descriptors "1.0.1"
methods "~1.1.2" methods "~1.1.2"
on-finished "~2.3.0" on-finished "2.4.1"
parseurl "~1.3.3" parseurl "~1.3.3"
path-to-regexp "0.1.7" path-to-regexp "0.1.7"
proxy-addr "~2.0.7" proxy-addr "~2.0.7"
qs "6.9.7" qs "6.10.3"
range-parser "~1.2.1" range-parser "~1.2.1"
safe-buffer "5.2.1" safe-buffer "5.2.1"
send "0.17.2" send "0.18.0"
serve-static "1.14.2" serve-static "1.15.0"
setprototypeof "1.2.0" setprototypeof "1.2.0"
statuses "~1.5.0" statuses "2.0.1"
type-is "~1.6.18" type-is "~1.6.18"
utils-merge "1.0.1" utils-merge "1.0.1"
vary "~1.1.2" vary "~1.1.2"
@@ -535,17 +510,17 @@ fill-range@^7.0.1:
dependencies: dependencies:
to-regex-range "^5.0.1" to-regex-range "^5.0.1"
finalhandler@~1.1.2: finalhandler@1.2.0:
version "1.1.2" version "1.2.0"
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32"
integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==
dependencies: dependencies:
debug "2.6.9" debug "2.6.9"
encodeurl "~1.0.2" encodeurl "~1.0.2"
escape-html "~1.0.3" escape-html "~1.0.3"
on-finished "~2.3.0" on-finished "2.4.1"
parseurl "~1.3.3" parseurl "~1.3.3"
statuses "~1.5.0" statuses "2.0.1"
unpipe "~1.0.0" unpipe "~1.0.0"
forwarded@0.2.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" resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= 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: http-errors@2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
@@ -1113,13 +1077,6 @@ on-finished@2.4.1:
dependencies: dependencies:
ee-first "1.1.1" 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: on-headers@~1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f"
@@ -1212,26 +1169,11 @@ qs@6.10.3:
dependencies: dependencies:
side-channel "^1.0.4" 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: range-parser@~1.2.1:
version "1.2.1" version "1.2.1"
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== 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: raw-body@2.5.1:
version "2.5.1" version "2.5.1"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857"
@@ -1351,24 +1293,24 @@ semver@^7.3.4:
dependencies: dependencies:
lru-cache "^6.0.0" lru-cache "^6.0.0"
send@0.17.2: send@0.18.0:
version "0.17.2" version "0.18.0"
resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820" resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"
integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww== integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==
dependencies: dependencies:
debug "2.6.9" debug "2.6.9"
depd "~1.1.2" depd "2.0.0"
destroy "~1.0.4" destroy "1.2.0"
encodeurl "~1.0.2" encodeurl "~1.0.2"
escape-html "~1.0.3" escape-html "~1.0.3"
etag "~1.8.1" etag "~1.8.1"
fresh "0.5.2" fresh "0.5.2"
http-errors "1.8.1" http-errors "2.0.0"
mime "1.6.0" mime "1.6.0"
ms "2.1.3" ms "2.1.3"
on-finished "~2.3.0" on-finished "2.4.1"
range-parser "~1.2.1" range-parser "~1.2.1"
statuses "~1.5.0" statuses "2.0.1"
serve-favicon@^2.4.2: serve-favicon@^2.4.2:
version "2.5.0" version "2.5.0"
@@ -1381,15 +1323,15 @@ serve-favicon@^2.4.2:
parseurl "~1.3.2" parseurl "~1.3.2"
safe-buffer "5.1.1" safe-buffer "5.1.1"
serve-static@1.14.2: serve-static@1.15.0:
version "1.14.2" version "1.15.0"
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540"
integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ== integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==
dependencies: dependencies:
encodeurl "~1.0.2" encodeurl "~1.0.2"
escape-html "~1.0.3" escape-html "~1.0.3"
parseurl "~1.3.3" parseurl "~1.3.3"
send "0.17.2" send "0.18.0"
setprototypeof@1.2.0: setprototypeof@1.2.0:
version "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" resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== 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: string-width@^3.0.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"