diff --git a/apps/oauth-mock-server/package.json b/apps/oauth-mock-server/package.json
index d79da5224..6d2b0fabe 100644
--- a/apps/oauth-mock-server/package.json
+++ b/apps/oauth-mock-server/package.json
@@ -10,8 +10,11 @@
"lint": "eslint ."
},
"dependencies": {
- "@types/oidc-provider": "^8.5.1",
"@stackframe/stack-shared": "workspace:*",
+ "@types/express": "^5.0.0",
+ "@types/oidc-provider": "^8.5.1",
+ "body-parser": "^1.20.3",
+ "express": "^4.21.2",
"oidc-provider": "^8.5.1"
},
"devDependencies": {
diff --git a/apps/oauth-mock-server/src/index.ts b/apps/oauth-mock-server/src/index.ts
index 00f31b5de..4ec8d98ec 100644
--- a/apps/oauth-mock-server/src/index.ts
+++ b/apps/oauth-mock-server/src/index.ts
@@ -1,41 +1,235 @@
-import Provider, { Configuration } from 'oidc-provider';
+import { strict as assert } from 'assert';
+import express from 'express';
+import Provider, { errors } from 'oidc-provider';
-// terminate this Node.js process if parent terminates
-process.on('disconnect', function() {
- console.log('parent exited; exiting too');
- process.exit();
-});
+const { SessionNotFound } = errors;
-const port = Number.parseInt(process.env.PORT || "8114");
-
-const mockedProviders = [
- "github",
- "facebook",
- "google",
- "microsoft",
- "spotify",
- "discord",
- "gitlab",
- "bitbucket",
- "x",
+const port = process.env.PORT || 8114;
+const providerIds = [
+ 'github',
+ 'facebook',
+ 'google',
+ 'microsoft',
+ 'spotify',
+ 'discord',
+ 'gitlab',
+ 'bitbucket',
+ 'x',
];
+const clients = providerIds.map((id) => ({
+ client_id: id,
+ client_secret: 'MOCK-SERVER-SECRET',
+ redirect_uris: [`http://localhost:8102/api/v1/auth/oauth/callback/${id}`],
+}));
-const configuration: Configuration = {
- clients: mockedProviders.map((providerId) => ({
- client_id: providerId,
- client_secret: 'MOCK-SERVER-SECRET',
- redirect_uris: [
- `http://localhost:8102/api/v1/auth/oauth/callback/${providerId}`,
- ],
- })),
- ttl: {
- // we make sessions short so it asks us for our login again after a minute, instead of automatically logging us in with the already-logged-in session
- Session: 60,
- },
+const configuration = {
+ clients,
+ ttl: { Session: 60 },
+ findAccount: async (ctx: any, sub: string) => ({
+ accountId: sub,
+ async claims() {
+ return { sub, email: sub };
+ },
+ }),
};
const oidc = new Provider(`http://localhost:${port}`, configuration);
+const app = express();
-oidc.listen(port, () => {
- console.log(`oidc-provider listening on port ${port}, check http://localhost:${port}/.well-known/openid-configuration`);
+app.use(express.urlencoded({ extended: false }));
+
+const renderLoginView = ({ uid, debugInfo }: { uid: string, debugInfo: unknown }): string => {
+ return `
+
+
+
+
+
+ Sign-in
+
+
+
+
+
+
Mock OAuth Sign-in
+
+
+
+
+ Debug
+ ${JSON.stringify(debugInfo, null, 2)}
+
+
+
+
+
+ `;
+};
+
+const setNoCache = (req: express.Request, res: express.Response, next: express.NextFunction) => {
+ res.set('cache-control', 'no-store');
+ next();
+};
+
+app.get('/interaction/:uid', setNoCache, async (req: express.Request, res: express.Response, next: express.NextFunction) => {
+ try {
+ const { uid, prompt, params, session, grantId } = await oidc.interactionDetails(req, res);
+ const debugInfo = { params, prompt, session };
+
+ if (prompt.name === 'login') {
+ res.send(renderLoginView({
+ uid,
+ debugInfo,
+ }));
+ } else if (prompt.name === 'consent') {
+ // Automatically approve consent without showing an approval page.
+ if (!session) throw new Error('No session found');
+ const accountId = session.accountId;
+ const { details } = prompt;
+
+ let grant = grantId
+ ? await oidc.Grant.find(grantId)
+ : new oidc.Grant({ accountId, clientId: params.client_id as string });
+ if (!grant) {
+ throw new Error('Failed to create or find grant');
+ }
+ if (Array.isArray(details.missingOIDCScope)) {
+ grant.addOIDCScope(details.missingOIDCScope.join(' '));
+ }
+ if (Array.isArray(details.missingOIDCClaims)) {
+ grant.addOIDCClaims(details.missingOIDCClaims);
+ }
+ if (details.missingResourceScopes && typeof details.missingResourceScopes === 'object') {
+ for (const [indicator, scopes] of Object.entries(details.missingResourceScopes)) {
+ if (Array.isArray(scopes)) {
+ grant.addResourceScope(indicator, scopes.join(' '));
+ }
+ }
+ }
+ const newGrantId = await grant.save();
+ const consent: { grantId?: string } = {};
+ if (!grantId) consent.grantId = newGrantId;
+ const result = { consent };
+ await oidc.interactionFinished(req, res, result, { mergeWithLastSubmission: true });
+ } else {
+ res.send('Unknown prompt');
+ }
+ } catch (err) {
+ next(err);
+ }
+});
+
+app.post('/interaction/:uid/login', setNoCache, async (req, res, next) => {
+ try {
+ const { prompt } = await oidc.interactionDetails(req, res);
+ assert.strictEqual(prompt.name, 'login', 'Expected login prompt');
+ const result = { login: { accountId: req.body.login, remember: false } };
+ await oidc.interactionFinished(req, res, result, { mergeWithLastSubmission: false });
+ } catch (err) {
+ next(err);
+ }
+});
+
+// The POST consent route has been removed as consent is now auto-approved.
+
+app.get('/interaction/:uid/abort', setNoCache, async (req, res, next) => {
+ try {
+ const result = {
+ error: 'access_denied',
+ error_description: 'End-User aborted interaction',
+ };
+ await oidc.interactionFinished(req, res, result, { mergeWithLastSubmission: false });
+ } catch (err) {
+ next(err);
+ }
+});
+
+app.use((err: any, req: express.Request, res: express.Response, next: express.NextFunction) => {
+ if (err instanceof SessionNotFound) {
+ res.status(410).send('Session not found or expired');
+ } else {
+ next(err);
+ }
+});
+
+app.use(oidc.callback());
+
+app.listen(port, () => {
+ console.log(`Server is running on http://localhost:${port}`);
});
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f6ec1bc68..fa24aaa26 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -419,9 +419,18 @@ importers:
'@stackframe/stack-shared':
specifier: workspace:*
version: link:../../packages/stack-shared
+ '@types/express':
+ specifier: ^5.0.0
+ version: 5.0.0
'@types/oidc-provider':
specifier: ^8.5.1
version: 8.5.1
+ body-parser:
+ specifier: ^1.20.3
+ version: 1.20.3
+ express:
+ specifier: ^4.21.2
+ version: 4.21.2
oidc-provider:
specifier: ^8.5.1
version: 8.5.1
@@ -5330,11 +5339,11 @@ packages:
'@types/estree@1.0.6':
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
- '@types/express-serve-static-core@4.19.5':
- resolution: {integrity: sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==}
+ '@types/express-serve-static-core@5.0.6':
+ resolution: {integrity: sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==}
- '@types/express@4.17.21':
- resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==}
+ '@types/express@5.0.0':
+ resolution: {integrity: sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==}
'@types/geojson@7946.0.15':
resolution: {integrity: sha512-9oSxFzDCT2Rj6DfcHF8G++jxBKS7mBqXl5xrRW+Kbvjry6Uduya2iiwqHPhVXpasAVMBYKkEPGgKhd3+/HZ6xA==}
@@ -5833,6 +5842,9 @@ packages:
resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==}
engines: {node: '>= 0.4'}
+ array-flatten@1.1.1:
+ resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==}
+
array-includes@3.1.8:
resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==}
engines: {node: '>= 0.4'}
@@ -6013,6 +6025,10 @@ packages:
bn.js@4.12.0:
resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==}
+ body-parser@1.20.3:
+ resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==}
+ engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
+
boolbase@1.0.0:
resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
@@ -6442,6 +6458,9 @@ packages:
convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
+ cookie-signature@1.0.6:
+ resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==}
+
cookie@0.4.2:
resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==}
engines: {node: '>= 0.6'}
@@ -6450,6 +6469,10 @@ packages:
resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==}
engines: {node: '>= 0.6'}
+ cookie@0.7.1:
+ resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==}
+ engines: {node: '>= 0.6'}
+
cookies@0.9.1:
resolution: {integrity: sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==}
engines: {node: '>= 0.8'}
@@ -6848,6 +6871,10 @@ packages:
resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==}
engines: {node: '>= 0.8'}
+ encodeurl@2.0.0:
+ resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
+ engines: {node: '>= 0.8'}
+
encoding-sniffer@0.2.0:
resolution: {integrity: sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==}
@@ -7209,6 +7236,10 @@ packages:
resolution: {integrity: sha512-tCsc7WXTjrTx4ZjYLplcqrI3o4mYJ+Z6YspeuGL8tbt/hHoMchwBwtKfwM09svEY86iRapY93vUqQttcNuIO5Q==}
engines: {node: '>=6.0.0'}
+ etag@1.8.1:
+ resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
+ engines: {node: '>= 0.6'}
+
eventemitter3@4.0.7:
resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==}
@@ -7232,6 +7263,10 @@ packages:
resolution: {integrity: sha512-6CX17Cu+rC2Fi2CyZ4CkgVG3hLl6BFsdAxfXiZkmDFIDY4mRx2y2spdeH6dqPHI9rP+AsHEfGeKz84Uuw7+Pmg==}
engines: {node: ^v12.20.0 || >=v14.13.0}
+ express@4.21.2:
+ resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==}
+ engines: {node: '>= 0.10.0'}
+
extend@3.0.2:
resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
@@ -7291,6 +7326,10 @@ packages:
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
engines: {node: '>=8'}
+ finalhandler@1.3.1:
+ resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==}
+ engines: {node: '>= 0.8'}
+
find-root@1.1.0:
resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==}
@@ -7354,6 +7393,10 @@ packages:
resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==}
engines: {node: '>= 6'}
+ forwarded@0.2.0:
+ resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
+ engines: {node: '>= 0.6'}
+
fraction.js@4.3.7:
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
@@ -7833,6 +7876,10 @@ packages:
resolution: {integrity: sha512-fOCG6lhoKKakwv+C6KdsOnGvgXnmgfmp0myi3bcNwj3qfwPAxRKWEuFhvEFF7ceYIz6+1jRZ+yguLFAmUNPEfw==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ ipaddr.js@1.9.1:
+ resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
+ engines: {node: '>= 0.10'}
+
ipaddr.js@2.2.0:
resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==}
engines: {node: '>= 10'}
@@ -8440,6 +8487,9 @@ packages:
resolution: {integrity: sha512-GWHvA5QOcS412WCo8vwKDlTelGLsCGBVevQB5Kva961rmNfun0PCbv5+xta2kUMFJyR8/oWnn7ddeKdosbAPbA==}
engines: {node: '>=10'}
+ merge-descriptors@1.0.3:
+ resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==}
+
merge-stream@2.0.0:
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
@@ -8583,6 +8633,11 @@ packages:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
+ mime@1.6.0:
+ resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
+ engines: {node: '>=4'}
+ hasBin: true
+
mimic-fn@2.1.0:
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
engines: {node: '>=6'}
@@ -8942,9 +8997,6 @@ packages:
resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
engines: {node: '>= 6'}
- object-inspect@1.13.1:
- resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==}
-
object-inspect@1.13.2:
resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==}
engines: {node: '>= 0.4'}
@@ -9144,6 +9196,9 @@ packages:
resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
engines: {node: '>=16 || 14 >=14.18'}
+ path-to-regexp@0.1.12:
+ resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==}
+
path-to-regexp@3.3.0:
resolution: {integrity: sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==}
@@ -9398,6 +9453,10 @@ packages:
resolution: {integrity: sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==}
engines: {node: '>=12.0.0'}
+ proxy-addr@2.0.7:
+ resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
+ engines: {node: '>= 0.10'}
+
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
@@ -9426,6 +9485,10 @@ packages:
engines: {node: '>=10.13.0'}
hasBin: true
+ qs@6.13.0:
+ resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==}
+ engines: {node: '>=0.6'}
+
querystringify@2.2.0:
resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==}
@@ -9460,6 +9523,10 @@ packages:
resolution: {integrity: sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==}
engines: {node: '>= 0.6'}
+ range-parser@1.2.1:
+ resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
+ engines: {node: '>= 0.6'}
+
raw-body@2.5.2:
resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==}
engines: {node: '>= 0.8'}
@@ -9904,12 +9971,20 @@ packages:
engines: {node: '>=10'}
hasBin: true
+ send@0.19.0:
+ resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==}
+ engines: {node: '>= 0.8.0'}
+
serialize-javascript@6.0.2:
resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==}
serve-handler@6.1.6:
resolution: {integrity: sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==}
+ serve-static@1.16.2:
+ resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==}
+ engines: {node: '>= 0.8.0'}
+
serve@14.2.4:
resolution: {integrity: sha512-qy1S34PJ/fcY8gjVGszDB3EXiPSk5FKhUa7tQe0UPRddxRidc2V6cNHPNewbE1D7MAkgLuWEt3Vw56vYy73tzQ==}
engines: {node: '>= 14'}
@@ -10812,6 +10887,10 @@ packages:
util@0.10.4:
resolution: {integrity: sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==}
+ utils-merge@1.0.1:
+ resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
+ engines: {node: '>= 0.4.0'}
+
uuid@9.0.1:
resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
hasBin: true
@@ -12290,7 +12369,7 @@ snapshots:
'@eslint/eslintrc@1.4.1':
dependencies:
ajv: 6.12.6
- debug: 4.3.5
+ debug: 4.3.7
espree: 9.6.1
globals: 13.24.0
ignore: 5.3.1
@@ -12382,7 +12461,7 @@ snapshots:
'@humanwhocodes/config-array@0.11.14':
dependencies:
'@humanwhocodes/object-schema': 2.0.3
- debug: 4.3.5
+ debug: 4.3.7
minimatch: 3.1.2
transitivePeerDependencies:
- supports-color
@@ -15434,7 +15513,7 @@ snapshots:
'@types/cookies@0.9.0':
dependencies:
'@types/connect': 3.4.38
- '@types/express': 4.17.21
+ '@types/express': 5.0.0
'@types/keygrip': 1.0.6
'@types/node': 20.17.6
@@ -15492,17 +15571,17 @@ snapshots:
'@types/estree@1.0.6': {}
- '@types/express-serve-static-core@4.19.5':
+ '@types/express-serve-static-core@5.0.6':
dependencies:
'@types/node': 20.17.6
'@types/qs': 6.9.15
'@types/range-parser': 1.2.7
'@types/send': 0.17.4
- '@types/express@4.17.21':
+ '@types/express@5.0.0':
dependencies:
'@types/body-parser': 1.19.5
- '@types/express-serve-static-core': 4.19.5
+ '@types/express-serve-static-core': 5.0.6
'@types/qs': 6.9.15
'@types/serve-static': 1.15.7
@@ -16049,6 +16128,8 @@ snapshots:
call-bind: 1.0.7
is-array-buffer: 3.0.4
+ array-flatten@1.1.1: {}
+
array-includes@3.1.8:
dependencies:
call-bind: 1.0.7
@@ -16288,6 +16369,23 @@ snapshots:
bn.js@4.12.0: {}
+ body-parser@1.20.3:
+ dependencies:
+ bytes: 3.1.2
+ content-type: 1.0.5
+ debug: 2.6.9
+ depd: 2.0.0
+ destroy: 1.2.0
+ http-errors: 2.0.0
+ iconv-lite: 0.4.24
+ on-finished: 2.4.1
+ qs: 6.13.0
+ raw-body: 2.5.2
+ type-is: 1.6.18
+ unpipe: 1.0.0
+ transitivePeerDependencies:
+ - supports-color
+
boolbase@1.0.0: {}
boxen@7.0.0:
@@ -16747,10 +16845,14 @@ snapshots:
convert-source-map@2.0.0: {}
+ cookie-signature@1.0.6: {}
+
cookie@0.4.2: {}
cookie@0.6.0: {}
+ cookie@0.7.1: {}
+
cookies@0.9.1:
dependencies:
depd: 2.0.0
@@ -17118,6 +17220,8 @@ snapshots:
encodeurl@1.0.2: {}
+ encodeurl@2.0.0: {}
+
encoding-sniffer@0.2.0:
dependencies:
iconv-lite: 0.6.3
@@ -17830,6 +17934,8 @@ snapshots:
eta@3.4.0: {}
+ etag@1.8.1: {}
+
eventemitter3@4.0.7: {}
events@3.3.0: {}
@@ -17862,6 +17968,42 @@ snapshots:
export-to-csv@1.4.0: {}
+ express@4.21.2:
+ dependencies:
+ accepts: 1.3.8
+ array-flatten: 1.1.1
+ body-parser: 1.20.3
+ content-disposition: 0.5.4
+ content-type: 1.0.5
+ cookie: 0.7.1
+ cookie-signature: 1.0.6
+ debug: 2.6.9
+ depd: 2.0.0
+ encodeurl: 2.0.0
+ escape-html: 1.0.3
+ etag: 1.8.1
+ finalhandler: 1.3.1
+ fresh: 0.5.2
+ http-errors: 2.0.0
+ merge-descriptors: 1.0.3
+ methods: 1.1.2
+ on-finished: 2.4.1
+ parseurl: 1.3.3
+ path-to-regexp: 0.1.12
+ proxy-addr: 2.0.7
+ qs: 6.13.0
+ range-parser: 1.2.1
+ safe-buffer: 5.2.1
+ send: 0.19.0
+ serve-static: 1.16.2
+ setprototypeof: 1.2.0
+ statuses: 2.0.1
+ type-is: 1.6.18
+ utils-merge: 1.0.1
+ vary: 1.1.2
+ transitivePeerDependencies:
+ - supports-color
+
extend@3.0.2: {}
extendable-error@0.1.7: {}
@@ -17912,6 +18054,18 @@ snapshots:
dependencies:
to-regex-range: 5.0.1
+ finalhandler@1.3.1:
+ dependencies:
+ debug: 2.6.9
+ encodeurl: 2.0.0
+ escape-html: 1.0.3
+ on-finished: 2.4.1
+ parseurl: 1.3.3
+ statuses: 2.0.1
+ unpipe: 1.0.0
+ transitivePeerDependencies:
+ - supports-color
+
find-root@1.1.0: {}
find-up@3.0.0:
@@ -17968,6 +18122,8 @@ snapshots:
combined-stream: 1.0.8
mime-types: 2.1.35
+ forwarded@0.2.0: {}
+
fraction.js@4.3.7: {}
frame-ticker@1.0.3:
@@ -18625,6 +18781,8 @@ snapshots:
ip-regex@5.0.0: {}
+ ipaddr.js@1.9.1: {}
+
ipaddr.js@2.2.0: {}
is-alphabetical@2.0.1: {}
@@ -19336,6 +19494,8 @@ snapshots:
type-fest: 0.13.1
yargs-parser: 18.1.3
+ merge-descriptors@1.0.3: {}
+
merge-stream@2.0.0: {}
merge2@1.4.1: {}
@@ -19638,6 +19798,8 @@ snapshots:
dependencies:
mime-db: 1.52.0
+ mime@1.6.0: {}
+
mimic-fn@2.1.0: {}
mimic-fn@4.0.0: {}
@@ -20050,8 +20212,6 @@ snapshots:
object-hash@3.0.0: {}
- object-inspect@1.13.1: {}
-
object-inspect@1.13.2: {}
object-keys@1.1.1: {}
@@ -20283,6 +20443,8 @@ snapshots:
lru-cache: 10.2.2
minipass: 7.1.2
+ path-to-regexp@0.1.12: {}
+
path-to-regexp@3.3.0: {}
path-to-regexp@6.2.2: {}
@@ -20557,6 +20719,11 @@ snapshots:
'@types/node': 20.17.6
long: 5.2.3
+ proxy-addr@2.0.7:
+ dependencies:
+ forwarded: 0.2.0
+ ipaddr.js: 1.9.1
+
proxy-from-env@1.1.0: {}
pseudomap@1.0.2: {}
@@ -20582,6 +20749,10 @@ snapshots:
pngjs: 5.0.0
yargs: 15.4.1
+ qs@6.13.0:
+ dependencies:
+ side-channel: 1.0.6
+
querystringify@2.2.0: {}
queue-microtask@1.2.3: {}
@@ -20608,6 +20779,8 @@ snapshots:
range-parser@1.2.0: {}
+ range-parser@1.2.1: {}
+
raw-body@2.5.2:
dependencies:
bytes: 3.1.2
@@ -21210,6 +21383,24 @@ snapshots:
semver@7.6.3: {}
+ send@0.19.0:
+ dependencies:
+ debug: 2.6.9
+ 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: 2.0.0
+ mime: 1.6.0
+ ms: 2.1.3
+ on-finished: 2.4.1
+ range-parser: 1.2.1
+ statuses: 2.0.1
+ transitivePeerDependencies:
+ - supports-color
+
serialize-javascript@6.0.2:
dependencies:
randombytes: 2.1.0
@@ -21224,6 +21415,15 @@ snapshots:
path-to-regexp: 3.3.0
range-parser: 1.2.0
+ serve-static@1.16.2:
+ dependencies:
+ encodeurl: 2.0.0
+ escape-html: 1.0.3
+ parseurl: 1.3.3
+ send: 0.19.0
+ transitivePeerDependencies:
+ - supports-color
+
serve@14.2.4:
dependencies:
'@zeit/schemas': 2.36.0
@@ -21354,7 +21554,7 @@ snapshots:
call-bind: 1.0.7
es-errors: 1.3.0
get-intrinsic: 1.2.4
- object-inspect: 1.13.1
+ object-inspect: 1.13.2
siginfo@2.0.0: {}
@@ -22418,6 +22618,8 @@ snapshots:
dependencies:
inherits: 2.0.3
+ utils-merge@1.0.1: {}
+
uuid@9.0.1: {}
uzip@0.20201231.0: {}