From b31227331710626c9aa90b39453d2ddcea9b6764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=B8vring?= Date: Thu, 24 Oct 2024 10:02:31 +0200 Subject: [PATCH 01/15] Cancels downloading when reaching 10 MB --- src/app/api/proxy/route.ts | 46 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/src/app/api/proxy/route.ts b/src/app/api/proxy/route.ts index 22226634..17a25256 100644 --- a/src/app/api/proxy/route.ts +++ b/src/app/api/proxy/route.ts @@ -17,6 +17,48 @@ export async function GET(req: NextRequest) { } catch { return makeAPIErrorResponse(400, "Invalid \"url\" query parameter.") } - const file = await fetch(url).then(r => r.blob()) - return new NextResponse(file, { status: 200 }) + try { + const maxBytes = 10 * 1024 * 1024 // 10 MB + const file = await downloadFile({ url, maxBytes }) + console.log("Downloaded") + return new NextResponse(file, { status: 200 }) + } catch (error) { + if (error instanceof Error == false) { + return makeAPIErrorResponse(500, "An unknown error occurred.") + } + if (error.name === "AbortError") { + return makeAPIErrorResponse(413, "The operation was aborted.") + } else if (error.name === "TimeoutError") { + return makeAPIErrorResponse(408, "The operation timed out.") + } else { + return makeAPIErrorResponse(500, error.message) + } + } +} + +async function downloadFile(params: { url: URL, maxBytes: number }): Promise { + const { url, maxBytes } = params + const abortController = new AbortController() + const response = await fetch(url, { + signal: AbortSignal.any([abortController.signal]) + }) + if (!response.body) { + throw new Error("Response body unavailable") + } + let totalBytes = 0 + const reader = response.body.getReader() + // eslint-disable-next-line no-constant-condition + while (true) { + // eslint-disable-next-line no-await-in-loop + const { done, value } = await reader.read() + if (done) { + break + } + totalBytes += value.length + if (totalBytes >= maxBytes) { + abortController.abort() + break + } + } + return await response.blob() } From 334b347ac73f7dc6b4e8f3f7565081be185d5564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=B8vring?= Date: Thu, 24 Oct 2024 10:02:41 +0200 Subject: [PATCH 02/15] Timeout downloading after 30 seconds --- src/app/api/proxy/route.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/api/proxy/route.ts b/src/app/api/proxy/route.ts index 17a25256..537000f5 100644 --- a/src/app/api/proxy/route.ts +++ b/src/app/api/proxy/route.ts @@ -39,8 +39,9 @@ export async function GET(req: NextRequest) { async function downloadFile(params: { url: URL, maxBytes: number }): Promise { const { url, maxBytes } = params const abortController = new AbortController() + const timeoutSignal = AbortSignal.timeout(30 * 1000) const response = await fetch(url, { - signal: AbortSignal.any([abortController.signal]) + signal: AbortSignal.any([abortController.signal, timeoutSignal]) }) if (!response.body) { throw new Error("Response body unavailable") From 62f0912b56c0bc67a23e64e22b649eb26707c0ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=B8vring?= Date: Thu, 24 Oct 2024 10:09:16 +0200 Subject: [PATCH 03/15] Removes debug log --- src/app/api/proxy/route.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/api/proxy/route.ts b/src/app/api/proxy/route.ts index 537000f5..7f5ae278 100644 --- a/src/app/api/proxy/route.ts +++ b/src/app/api/proxy/route.ts @@ -20,7 +20,6 @@ export async function GET(req: NextRequest) { try { const maxBytes = 10 * 1024 * 1024 // 10 MB const file = await downloadFile({ url, maxBytes }) - console.log("Downloaded") return new NextResponse(file, { status: 200 }) } catch (error) { if (error instanceof Error == false) { From 884500148669bc17bb3e3844528e782eb83e6202 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=B8vring?= Date: Thu, 24 Oct 2024 10:20:25 +0200 Subject: [PATCH 04/15] Makes max file size and timeout configurable --- .env.example | 2 ++ src/app/api/proxy/route.ts | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/.env.example b/.env.example index d69da90c..1e98a941 100644 --- a/.env.example +++ b/.env.example @@ -13,6 +13,8 @@ POSTGRESQL_DB=framna-docs REPOSITORY_NAME_SUFFIX=-openapi HIDDEN_REPOSITORIES= NEW_PROJECT_TEMPLATE_REPOSITORY=shapehq/starter-openapi +PROXY_API_MAXIMUM_FILE_SIZE_IN_MEGABYTES = 10 +PROXY_API_TIMEOUT_IN_SECONDS = 30 GITHUB_WEBHOOK_SECRET=preshared secret also put in app configuration in GitHub GITHUB_WEBHOK_REPOSITORY_ALLOWLIST= GITHUB_WEBHOK_REPOSITORY_DISALLOWLIST= diff --git a/src/app/api/proxy/route.ts b/src/app/api/proxy/route.ts index 7f5ae278..0af1c4cd 100644 --- a/src/app/api/proxy/route.ts +++ b/src/app/api/proxy/route.ts @@ -1,6 +1,7 @@ import { NextRequest, NextResponse } from "next/server" import { makeAPIErrorResponse, makeUnauthenticatedAPIErrorResponse } from "@/common" import { session } from "@/composition" +import { env } from "@/common" export async function GET(req: NextRequest) { const isAuthenticated = await session.getIsAuthenticated() @@ -18,8 +19,10 @@ export async function GET(req: NextRequest) { return makeAPIErrorResponse(400, "Invalid \"url\" query parameter.") } try { - const maxBytes = 10 * 1024 * 1024 // 10 MB - const file = await downloadFile({ url, maxBytes }) + const maxMegabytes = Number(env.getOrThrow("PROXY_API_MAXIMUM_FILE_SIZE_IN_MEGABYTES")) + const timeoutInSeconds = Number(env.getOrThrow("PROXY_API_TIMEOUT_IN_SECONDS")) + const maxBytes = maxMegabytes * 1024 * 1024 + const file = await downloadFile({ url, maxBytes, timeoutInSeconds }) return new NextResponse(file, { status: 200 }) } catch (error) { if (error instanceof Error == false) { @@ -35,10 +38,14 @@ export async function GET(req: NextRequest) { } } -async function downloadFile(params: { url: URL, maxBytes: number }): Promise { - const { url, maxBytes } = params +async function downloadFile(params: { + url: URL, + maxBytes: number, + timeoutInSeconds: number +}): Promise { + const { url, maxBytes, timeoutInSeconds } = params const abortController = new AbortController() - const timeoutSignal = AbortSignal.timeout(30 * 1000) + const timeoutSignal = AbortSignal.timeout(timeoutInSeconds * 1000) const response = await fetch(url, { signal: AbortSignal.any([abortController.signal, timeoutSignal]) }) From d6dbfb3fe7ab525cace39a0cf3a5f8da2a1bfe4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=B8vring?= Date: Thu, 24 Oct 2024 10:20:54 +0200 Subject: [PATCH 05/15] Fixes blob not returned correctly --- src/app/api/proxy/route.ts | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/app/api/proxy/route.ts b/src/app/api/proxy/route.ts index 0af1c4cd..5d6b8c02 100644 --- a/src/app/api/proxy/route.ts +++ b/src/app/api/proxy/route.ts @@ -3,6 +3,11 @@ import { makeAPIErrorResponse, makeUnauthenticatedAPIErrorResponse } from "@/com import { session } from "@/composition" import { env } from "@/common" +const ErrorName = { + MAX_FILE_SIZE_EXCEEDED: "MaxFileSizeExceededError", + TIMEOUT: "TimeoutError" +} + export async function GET(req: NextRequest) { const isAuthenticated = await session.getIsAuthenticated() if (!isAuthenticated) { @@ -25,12 +30,13 @@ export async function GET(req: NextRequest) { const file = await downloadFile({ url, maxBytes, timeoutInSeconds }) return new NextResponse(file, { status: 200 }) } catch (error) { + console.log(error) if (error instanceof Error == false) { return makeAPIErrorResponse(500, "An unknown error occurred.") } - if (error.name === "AbortError") { + if (error.name === ErrorName.MAX_FILE_SIZE_EXCEEDED) { return makeAPIErrorResponse(413, "The operation was aborted.") - } else if (error.name === "TimeoutError") { + } else if (error.name === ErrorName.TIMEOUT) { return makeAPIErrorResponse(408, "The operation timed out.") } else { return makeAPIErrorResponse(500, error.message) @@ -53,7 +59,9 @@ async function downloadFile(params: { throw new Error("Response body unavailable") } let totalBytes = 0 + let didExceedMaxBytes = false const reader = response.body.getReader() + let chunks: Uint8Array[] = [] // eslint-disable-next-line no-constant-condition while (true) { // eslint-disable-next-line no-await-in-loop @@ -62,10 +70,17 @@ async function downloadFile(params: { break } totalBytes += value.length + chunks.push(value) if (totalBytes >= maxBytes) { + didExceedMaxBytes = true abortController.abort() break } } - return await response.blob() + if (didExceedMaxBytes) { + const error = new Error("Maximum file size exceeded") + error.name = ErrorName.MAX_FILE_SIZE_EXCEEDED + throw error + } + return new Blob(chunks) } From f1b540f017b62779257d2a9ce1d3e96514ed0115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=B8vring?= Date: Thu, 24 Oct 2024 11:37:40 +0200 Subject: [PATCH 06/15] Removes error logging --- src/app/api/proxy/route.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/api/proxy/route.ts b/src/app/api/proxy/route.ts index 5d6b8c02..413c11b6 100644 --- a/src/app/api/proxy/route.ts +++ b/src/app/api/proxy/route.ts @@ -30,7 +30,6 @@ export async function GET(req: NextRequest) { const file = await downloadFile({ url, maxBytes, timeoutInSeconds }) return new NextResponse(file, { status: 200 }) } catch (error) { - console.log(error) if (error instanceof Error == false) { return makeAPIErrorResponse(500, "An unknown error occurred.") } From f1f9296f0e1ed6c4cfb6eccdda0e3fb257afc42a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=B8vring?= Date: Thu, 24 Oct 2024 11:43:21 +0200 Subject: [PATCH 07/15] Fixes linting errors --- src/app/api/proxy/route.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/app/api/proxy/route.ts b/src/app/api/proxy/route.ts index 413c11b6..7b96c170 100644 --- a/src/app/api/proxy/route.ts +++ b/src/app/api/proxy/route.ts @@ -1,7 +1,6 @@ import { NextRequest, NextResponse } from "next/server" -import { makeAPIErrorResponse, makeUnauthenticatedAPIErrorResponse } from "@/common" +import { env, makeAPIErrorResponse, makeUnauthenticatedAPIErrorResponse } from "@/common" import { session } from "@/composition" -import { env } from "@/common" const ErrorName = { MAX_FILE_SIZE_EXCEEDED: "MaxFileSizeExceededError", @@ -60,7 +59,7 @@ async function downloadFile(params: { let totalBytes = 0 let didExceedMaxBytes = false const reader = response.body.getReader() - let chunks: Uint8Array[] = [] + const chunks: Uint8Array[] = [] // eslint-disable-next-line no-constant-condition while (true) { // eslint-disable-next-line no-await-in-loop From 287662e50744328d62efe4ea9c6136e958e81fae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 07:30:04 +0000 Subject: [PATCH 08/15] Bump the mui group with 2 updates Bumps the mui group with 2 updates: [@mui/icons-material](https://github.com/mui/material-ui/tree/HEAD/packages/mui-icons-material) and [@mui/material](https://github.com/mui/material-ui/tree/HEAD/packages/mui-material). Updates `@mui/icons-material` from 6.1.4 to 6.1.5 - [Release notes](https://github.com/mui/material-ui/releases) - [Changelog](https://github.com/mui/material-ui/blob/master/CHANGELOG.md) - [Commits](https://github.com/mui/material-ui/commits/v6.1.5/packages/mui-icons-material) Updates `@mui/material` from 6.1.4 to 6.1.5 - [Release notes](https://github.com/mui/material-ui/releases) - [Changelog](https://github.com/mui/material-ui/blob/master/CHANGELOG.md) - [Commits](https://github.com/mui/material-ui/commits/v6.1.5/packages/mui-material) --- updated-dependencies: - dependency-name: "@mui/icons-material" dependency-type: direct:production update-type: version-update:semver-patch dependency-group: mui - dependency-name: "@mui/material" dependency-type: direct:production update-type: version-update:semver-patch dependency-group: mui ... Signed-off-by: dependabot[bot] --- package-lock.json | 62 +++++++++++++++++++++++------------------------ package.json | 2 +- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/package-lock.json b/package-lock.json index bba1ed92..176c346b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "@fortawesome/free-regular-svg-icons": "^6.6.0", "@fortawesome/free-solid-svg-icons": "^6.6.0", "@fortawesome/react-fontawesome": "^0.2.2", - "@mui/icons-material": "^6.1.4", + "@mui/icons-material": "^6.1.5", "@mui/material": "^6.0.1", "@octokit/auth-app": "^7.1.1", "@octokit/core": "^6.1.2", @@ -2031,18 +2031,18 @@ "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==" }, "node_modules/@mui/core-downloads-tracker": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.4.tgz", - "integrity": "sha512-jCRsB9NDJJatVCHvwWSTfYUzuTQ7E0Km6tAQWz2Md1SLHIbVj5visC9yHbf/Cv2IDcG6XdHRv3e7Bt1rIburNw==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.5.tgz", + "integrity": "sha512-3J96098GrC95XsLw/TpGNMxhUOnoG9NZ/17Pfk1CrJj+4rcuolsF2RdF3XAFTu/3a/A+5ouxlSIykzYz6Ee87g==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" } }, "node_modules/@mui/icons-material": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.1.4.tgz", - "integrity": "sha512-nhXBNSP3WkY0pz8dg25VIYIXJkhdRLRKZtD50f9OuHVQ1eh8b+enmvaZQF0o5M8cs1sR6wQHwZYwG34qDZeG0g==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.1.5.tgz", + "integrity": "sha512-SbxFtO5I4cXfvhjAMgGib/t2lQUzcEzcDFYiRHRufZUeMMeXuoKaGsptfwAHTepYkv0VqcCwvxtvtWbpZLAbjQ==", "dependencies": { "@babel/runtime": "^7.25.7" }, @@ -2054,7 +2054,7 @@ "url": "https://opencollective.com/mui-org" }, "peerDependencies": { - "@mui/material": "^6.1.4", + "@mui/material": "^6.1.5", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, @@ -2065,15 +2065,15 @@ } }, "node_modules/@mui/material": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.1.4.tgz", - "integrity": "sha512-mIVdjzDYU4U/XYzf8pPEz3zDZFS4Wbyr0cjfgeGiT/s60EvtEresXXQy8XUA0bpJDJjgic1Hl5AIRcqWDyi2eg==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.1.5.tgz", + "integrity": "sha512-rhaxC7LnlOG8zIVYv7BycNbWkC5dlm9A/tcDUp0CuwA7Zf9B9JP6M3rr50cNKxI7Z0GIUesAT86ceVm44quwnQ==", "dependencies": { "@babel/runtime": "^7.25.7", - "@mui/core-downloads-tracker": "^6.1.4", - "@mui/system": "^6.1.4", + "@mui/core-downloads-tracker": "^6.1.5", + "@mui/system": "^6.1.5", "@mui/types": "^7.2.18", - "@mui/utils": "^6.1.4", + "@mui/utils": "^6.1.5", "@popperjs/core": "^2.11.8", "@types/react-transition-group": "^4.4.11", "clsx": "^2.1.1", @@ -2092,7 +2092,7 @@ "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@mui/material-pigment-css": "^6.1.4", + "@mui/material-pigment-css": "^6.1.5", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" @@ -2113,12 +2113,12 @@ } }, "node_modules/@mui/private-theming": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.1.4.tgz", - "integrity": "sha512-FPa+W5BSrRM/1QI5Gf/GwJinJ2WsrKPpJB6xMmmXMXSUIp31YioIVT04i28DQUXFFB3yZY12ukcZi51iLvPljw==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.1.5.tgz", + "integrity": "sha512-FJqweqEXk0KdtTho9C2h6JEKXsOT7MAVH2Uj3N5oIqs6YKxnwBn2/zL2QuYYEtj5OJ87rEUnCfFic6ldClvzJw==", "dependencies": { "@babel/runtime": "^7.25.7", - "@mui/utils": "^6.1.4", + "@mui/utils": "^6.1.5", "prop-types": "^15.8.1" }, "engines": { @@ -2139,9 +2139,9 @@ } }, "node_modules/@mui/styled-engine": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.1.4.tgz", - "integrity": "sha512-D+aiIDtJsU9OVJ7dgayhCDABJHT7jTlnz1FKyxa5mNVHsxjjeG1M4OpLsRQvx4dcvJfDywnU2cE+nFm4Ln2aFQ==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.1.5.tgz", + "integrity": "sha512-tiyWzMkHeWlOoE6AqomWvYvdml8Nv5k5T+LDwOiwHEawx8P9Lyja6ZwWPU6xljwPXYYPT2KBp1XvMly7dsK46A==", "dependencies": { "@babel/runtime": "^7.25.7", "@emotion/cache": "^11.13.1", @@ -2172,15 +2172,15 @@ } }, "node_modules/@mui/system": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.1.4.tgz", - "integrity": "sha512-lCveY/UtDhYwMg1WnLc3wEEuGymLi6YI79VOwFV9zfZT5Et+XEw/e1It26fiKwUZ+mB1+v1iTYMpJnwnsrn2aQ==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.1.5.tgz", + "integrity": "sha512-vPM9ocQ8qquRDByTG3XF/wfYTL7IWL/20EiiKqByLDps8wOmbrDG9rVznSE3ZbcjFCFfMRMhtxvN92bwe/63SA==", "dependencies": { "@babel/runtime": "^7.25.7", - "@mui/private-theming": "^6.1.4", - "@mui/styled-engine": "^6.1.4", + "@mui/private-theming": "^6.1.5", + "@mui/styled-engine": "^6.1.5", "@mui/types": "^7.2.18", - "@mui/utils": "^6.1.4", + "@mui/utils": "^6.1.5", "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1" @@ -2224,9 +2224,9 @@ } }, "node_modules/@mui/utils": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.1.4.tgz", - "integrity": "sha512-v0wXkyh3/Hpw48ivlNvgs4ZT6M8BIEAMdLgvct59rQBggYFhoAVKyliKDzdj37CnIlYau3DYIn7x5bHlRYFBow==", + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.1.5.tgz", + "integrity": "sha512-vp2WfNDY+IbKUIGg+eqX1Ry4t/BilMjzp6p9xO1rfqpYjH1mj8coQxxDfKxcQLzBQkmBJjymjoGOak5VUYwXug==", "dependencies": { "@babel/runtime": "^7.25.7", "@mui/types": "^7.2.18", diff --git a/package.json b/package.json index 60756f63..5c448dfe 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "@fortawesome/free-regular-svg-icons": "^6.6.0", "@fortawesome/free-solid-svg-icons": "^6.6.0", "@fortawesome/react-fontawesome": "^0.2.2", - "@mui/icons-material": "^6.1.4", + "@mui/icons-material": "^6.1.5", "@mui/material": "^6.0.1", "@octokit/auth-app": "^7.1.1", "@octokit/core": "^6.1.2", From c1a5b4d49a47c95795ac53d3bb28471769f2e609 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 08:04:36 +0000 Subject: [PATCH 09/15] Bump pg and @types/pg Bumps [pg](https://github.com/brianc/node-postgres/tree/HEAD/packages/pg) and [@types/pg](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/pg). These dependencies needed to be updated together. Updates `pg` from 8.12.0 to 8.13.1 - [Changelog](https://github.com/brianc/node-postgres/blob/master/CHANGELOG.md) - [Commits](https://github.com/brianc/node-postgres/commits/pg@8.13.1/packages/pg) Updates `@types/pg` from 8.11.6 to 8.11.10 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/pg) --- updated-dependencies: - dependency-name: pg dependency-type: direct:development update-type: version-update:semver-minor - dependency-name: "@types/pg" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 40 ++++++++++++++++++++-------------------- package.json | 4 ++-- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/package-lock.json b/package-lock.json index 176c346b..138cd9a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,7 +50,7 @@ "@types/jest": "^29.5.12", "@types/node": "^22.7.4", "@types/nprogress": "^0.2.3", - "@types/pg": "^8.11.6", + "@types/pg": "^8.11.10", "@types/react": "^18.3.11", "@types/react-dom": "^18.3.0", "@types/swagger-ui-react": "^4.18.3", @@ -59,7 +59,7 @@ "autoprefixer": "^10.4.20", "eslint": "^8.57.1", "eslint-config-next": "^14.2.14", - "pg": "^8.12.0", + "pg": "^8.13.1", "postcss": "^8.4.41", "tailwindcss": "^3.4.13", "ts-jest": "^29.2.5", @@ -4474,9 +4474,9 @@ "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==" }, "node_modules/@types/pg": { - "version": "8.11.6", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.11.6.tgz", - "integrity": "sha512-/2WmmBXHLsfRqzfHW7BNZ8SbYzE8OSk7i3WjFYvfgRHj7S1xj+16Je5fUKv3lVdVzk/zn9TXOqf+avFCFIE0yQ==", + "version": "8.11.10", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.11.10.tgz", + "integrity": "sha512-LczQUW4dbOQzsH2RQ5qoeJ6qJPdrcM/DcMLoqWQkMLMsq83J5lAX3LXjdkWdpscFy67JSOWDnh7Ny/sPFykmkg==", "dev": true, "dependencies": { "@types/node": "*", @@ -16262,14 +16262,14 @@ "peer": true }, "node_modules/pg": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.12.0.tgz", - "integrity": "sha512-A+LHUSnwnxrnL/tZ+OLfqR1SxLN3c/pgDztZ47Rpbsd4jUytsTtwQo/TLPRzPJMp/1pbhYVhH9cuSZLAajNfjQ==", + "version": "8.13.1", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.13.1.tgz", + "integrity": "sha512-OUir1A0rPNZlX//c7ksiu7crsGZTKSOXJPgtNiHGIlC9H0lO+NC6ZDYksSgBYY/thSWhnSRBv8w1lieNNGATNQ==", "dev": true, "dependencies": { - "pg-connection-string": "^2.6.4", - "pg-pool": "^3.6.2", - "pg-protocol": "^1.6.1", + "pg-connection-string": "^2.7.0", + "pg-pool": "^3.7.0", + "pg-protocol": "^1.7.0", "pg-types": "^2.1.0", "pgpass": "1.x" }, @@ -16296,9 +16296,9 @@ "optional": true }, "node_modules/pg-connection-string": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.4.tgz", - "integrity": "sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.7.0.tgz", + "integrity": "sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA==", "dev": true }, "node_modules/pg-int8": { @@ -16320,18 +16320,18 @@ } }, "node_modules/pg-pool": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.2.tgz", - "integrity": "sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.7.0.tgz", + "integrity": "sha512-ZOBQForurqh4zZWjrgSwwAtzJ7QiRX0ovFkZr2klsen3Nm0aoh33Ls0fzfv3imeH/nw/O27cjdz5kzYJfeGp/g==", "dev": true, "peerDependencies": { "pg": ">=8.0" } }, "node_modules/pg-protocol": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.1.tgz", - "integrity": "sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.7.0.tgz", + "integrity": "sha512-hTK/mE36i8fDDhgDFjy6xNOG+LCorxLG3WO17tku+ij6sVHXh1jQUJ8hYAnRhNla4QVD2H8er/FOjc/+EgC6yQ==", "dev": true }, "node_modules/pg-types": { diff --git a/package.json b/package.json index 5c448dfe..dc6731f3 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "@types/jest": "^29.5.12", "@types/node": "^22.7.4", "@types/nprogress": "^0.2.3", - "@types/pg": "^8.11.6", + "@types/pg": "^8.11.10", "@types/react": "^18.3.11", "@types/react-dom": "^18.3.0", "@types/swagger-ui-react": "^4.18.3", @@ -66,7 +66,7 @@ "autoprefixer": "^10.4.20", "eslint": "^8.57.1", "eslint-config-next": "^14.2.14", - "pg": "^8.12.0", + "pg": "^8.13.1", "postcss": "^8.4.41", "tailwindcss": "^3.4.13", "ts-jest": "^29.2.5", From 2f78370cbe97ac3bf7b55d37e75e3185fdaf13bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 08:08:22 +0000 Subject: [PATCH 10/15] Bump @fontsource/poppins from 5.0.14 to 5.1.0 Bumps [@fontsource/poppins](https://github.com/fontsource/font-files/tree/HEAD/fonts/google/poppins) from 5.0.14 to 5.1.0. - [Changelog](https://github.com/fontsource/font-files/blob/main/CHANGELOG.md) - [Commits](https://github.com/fontsource/font-files/commits/HEAD/fonts/google/poppins) --- updated-dependencies: - dependency-name: "@fontsource/poppins" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 138cd9a8..4acc74de 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "dependencies": { "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", - "@fontsource/poppins": "^5.0.14", + "@fontsource/poppins": "^5.1.0", "@fortawesome/fontawesome-svg-core": "^6.6.0", "@fortawesome/free-brands-svg-icons": "^6.6.0", "@fortawesome/free-regular-svg-icons": "^6.6.0", @@ -934,9 +934,9 @@ "deprecated": "Please update to a newer version." }, "node_modules/@fontsource/poppins": { - "version": "5.0.14", - "resolved": "https://registry.npmjs.org/@fontsource/poppins/-/poppins-5.0.14.tgz", - "integrity": "sha512-nmM1zpPo3Uh4JcGAVSQuWaZNYh2FbbwWhZ5t6hRaynmJaNTBW85d3nEh9zMmzI0HX7X5xqQVdRHeDatKpOGsnA==" + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@fontsource/poppins/-/poppins-5.1.0.tgz", + "integrity": "sha512-tpLXlnNi2fwQjiipvuj4uNFHCdoLA8izRsKdoexZuEzjx0r/g1aKLf4ta6lFgF7L+/+AFdmaXFlUwwvmDzYH+g==" }, "node_modules/@fortawesome/fontawesome-common-types": { "version": "6.6.0", diff --git a/package.json b/package.json index dc6731f3..596d3164 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "dependencies": { "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", - "@fontsource/poppins": "^5.0.14", + "@fontsource/poppins": "^5.1.0", "@fortawesome/fontawesome-svg-core": "^6.6.0", "@fortawesome/free-brands-svg-icons": "^6.6.0", "@fortawesome/free-regular-svg-icons": "^6.6.0", From 84a462dd9e288d8f54b80b4b0e827d83b1eb5681 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 08:12:30 +0000 Subject: [PATCH 11/15] Bump the typescript-eslint group with 2 updates Bumps the typescript-eslint group with 2 updates: [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) and [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser). Updates `@typescript-eslint/eslint-plugin` from 8.10.0 to 8.11.0 - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.11.0/packages/eslint-plugin) Updates `@typescript-eslint/parser` from 8.10.0 to 8.11.0 - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.11.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor dependency-group: typescript-eslint - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor dependency-group: typescript-eslint ... Signed-off-by: dependabot[bot] --- package-lock.json | 88 +++++++++++++++++++++++------------------------ package.json | 4 +-- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4acc74de..f56ee671 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,8 +54,8 @@ "@types/react": "^18.3.11", "@types/react-dom": "^18.3.0", "@types/swagger-ui-react": "^4.18.3", - "@typescript-eslint/eslint-plugin": "^8.10.0", - "@typescript-eslint/parser": "^8.10.0", + "@typescript-eslint/eslint-plugin": "^8.11.0", + "@typescript-eslint/parser": "^8.11.0", "autoprefixer": "^10.4.20", "eslint": "^8.57.1", "eslint-config-next": "^14.2.14", @@ -4587,16 +4587,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.10.0.tgz", - "integrity": "sha512-phuB3hoP7FFKbRXxjl+DRlQDuJqhpOnm5MmtROXyWi3uS/Xg2ZXqiQfcG2BJHiN4QKyzdOJi3NEn/qTnjUlkmQ==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.11.0.tgz", + "integrity": "sha512-KhGn2LjW1PJT2A/GfDpiyOfS4a8xHQv2myUagTM5+zsormOmBlYsnQ6pobJ8XxJmh6hnHwa2Mbe3fPrDJoDhbA==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.10.0", - "@typescript-eslint/type-utils": "8.10.0", - "@typescript-eslint/utils": "8.10.0", - "@typescript-eslint/visitor-keys": "8.10.0", + "@typescript-eslint/scope-manager": "8.11.0", + "@typescript-eslint/type-utils": "8.11.0", + "@typescript-eslint/utils": "8.11.0", + "@typescript-eslint/visitor-keys": "8.11.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -4620,15 +4620,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.10.0.tgz", - "integrity": "sha512-E24l90SxuJhytWJ0pTQydFT46Nk0Z+bsLKo/L8rtQSL93rQ6byd1V/QbDpHUTdLPOMsBCcYXZweADNCfOCmOAg==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.11.0.tgz", + "integrity": "sha512-lmt73NeHdy1Q/2ul295Qy3uninSqi6wQI18XwSpm8w0ZbQXUpjCAWP1Vlv/obudoBiIjJVjlztjQ+d/Md98Yxg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.10.0", - "@typescript-eslint/types": "8.10.0", - "@typescript-eslint/typescript-estree": "8.10.0", - "@typescript-eslint/visitor-keys": "8.10.0", + "@typescript-eslint/scope-manager": "8.11.0", + "@typescript-eslint/types": "8.11.0", + "@typescript-eslint/typescript-estree": "8.11.0", + "@typescript-eslint/visitor-keys": "8.11.0", "debug": "^4.3.4" }, "engines": { @@ -4648,13 +4648,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.10.0.tgz", - "integrity": "sha512-AgCaEjhfql9MDKjMUxWvH7HjLeBqMCBfIaBbzzIcBbQPZE7CPh1m6FF+L75NUMJFMLYhCywJXIDEMa3//1A0dw==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.11.0.tgz", + "integrity": "sha512-Uholz7tWhXmA4r6epo+vaeV7yjdKy5QFCERMjs1kMVsLRKIrSdM6o21W2He9ftp5PP6aWOVpD5zvrvuHZC0bMQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.10.0", - "@typescript-eslint/visitor-keys": "8.10.0" + "@typescript-eslint/types": "8.11.0", + "@typescript-eslint/visitor-keys": "8.11.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4665,13 +4665,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.10.0.tgz", - "integrity": "sha512-PCpUOpyQSpxBn230yIcK+LeCQaXuxrgCm2Zk1S+PTIRJsEfU6nJ0TtwyH8pIwPK/vJoA+7TZtzyAJSGBz+s/dg==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.11.0.tgz", + "integrity": "sha512-ItiMfJS6pQU0NIKAaybBKkuVzo6IdnAhPFZA/2Mba/uBjuPQPet/8+zh5GtLHwmuFRShZx+8lhIs7/QeDHflOg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "8.10.0", - "@typescript-eslint/utils": "8.10.0", + "@typescript-eslint/typescript-estree": "8.11.0", + "@typescript-eslint/utils": "8.11.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -4689,9 +4689,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.10.0.tgz", - "integrity": "sha512-k/E48uzsfJCRRbGLapdZgrX52csmWJ2rcowwPvOZ8lwPUv3xW6CcFeJAXgx4uJm+Ge4+a4tFOkdYvSpxhRhg1w==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.11.0.tgz", + "integrity": "sha512-tn6sNMHf6EBAYMvmPUaKaVeYvhUsrE6x+bXQTxjQRp360h1giATU0WvgeEys1spbvb5R+VpNOZ+XJmjD8wOUHw==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4702,13 +4702,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.10.0.tgz", - "integrity": "sha512-3OE0nlcOHaMvQ8Xu5gAfME3/tWVDpb/HxtpUZ1WeOAksZ/h/gwrBzCklaGzwZT97/lBbbxJ16dMA98JMEngW4w==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.11.0.tgz", + "integrity": "sha512-yHC3s1z1RCHoCz5t06gf7jH24rr3vns08XXhfEqzYpd6Hll3z/3g23JRi0jM8A47UFKNc3u/y5KIMx8Ynbjohg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.10.0", - "@typescript-eslint/visitor-keys": "8.10.0", + "@typescript-eslint/types": "8.11.0", + "@typescript-eslint/visitor-keys": "8.11.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -4730,15 +4730,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.10.0.tgz", - "integrity": "sha512-Oq4uZ7JFr9d1ZunE/QKy5egcDRXT/FrS2z/nlxzPua2VHFtmMvFNDvpq1m/hq0ra+T52aUezfcjGRIB7vNJF9w==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.11.0.tgz", + "integrity": "sha512-CYiX6WZcbXNJV7UNB4PLDIBtSdRmRI/nb0FMyqHPTQD1rMjA0foPLaPUV39C/MxkTd/QKSeX+Gb34PPsDVC35g==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.10.0", - "@typescript-eslint/types": "8.10.0", - "@typescript-eslint/typescript-estree": "8.10.0" + "@typescript-eslint/scope-manager": "8.11.0", + "@typescript-eslint/types": "8.11.0", + "@typescript-eslint/typescript-estree": "8.11.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4752,12 +4752,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.10.0.tgz", - "integrity": "sha512-k8nekgqwr7FadWk548Lfph6V3r9OVqjzAIVskE7orMZR23cGJjAOVazsZSJW+ElyjfTM4wx/1g88Mi70DDtG9A==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.11.0.tgz", + "integrity": "sha512-EaewX6lxSjRJnc+99+dqzTeoDZUfyrA52d2/HRrkI830kgovWsmIiTfmr0NZorzqic7ga+1bS60lRBUgR3n/Bw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.10.0", + "@typescript-eslint/types": "8.11.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { diff --git a/package.json b/package.json index 596d3164..aa3a5aaf 100644 --- a/package.json +++ b/package.json @@ -61,8 +61,8 @@ "@types/react": "^18.3.11", "@types/react-dom": "^18.3.0", "@types/swagger-ui-react": "^4.18.3", - "@typescript-eslint/eslint-plugin": "^8.10.0", - "@typescript-eslint/parser": "^8.10.0", + "@typescript-eslint/eslint-plugin": "^8.11.0", + "@typescript-eslint/parser": "^8.11.0", "autoprefixer": "^10.4.20", "eslint": "^8.57.1", "eslint-config-next": "^14.2.14", From 26c7ffd6a4d30fd4f7063762c37097ce0025a602 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 08:16:22 +0000 Subject: [PATCH 12/15] Bump @types/react from 18.3.11 to 18.3.12 Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 18.3.11 to 18.3.12. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react) --- updated-dependencies: - dependency-name: "@types/react" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index f56ee671..79f84ab8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,7 +51,7 @@ "@types/node": "^22.7.4", "@types/nprogress": "^0.2.3", "@types/pg": "^8.11.10", - "@types/react": "^18.3.11", + "@types/react": "^18.3.12", "@types/react-dom": "^18.3.0", "@types/swagger-ui-react": "^4.18.3", "@typescript-eslint/eslint-plugin": "^8.11.0", @@ -4498,9 +4498,9 @@ } }, "node_modules/@types/react": { - "version": "18.3.11", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.11.tgz", - "integrity": "sha512-r6QZ069rFTjrEYgFdOck1gK7FLVsgJE7tTz0pQBczlBNUhBNk0MQH4UbnFSwjpQLMkLzgqvBBa+qGpLje16eTQ==", + "version": "18.3.12", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz", + "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" diff --git a/package.json b/package.json index aa3a5aaf..4e7921f4 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "@types/node": "^22.7.4", "@types/nprogress": "^0.2.3", "@types/pg": "^8.11.10", - "@types/react": "^18.3.11", + "@types/react": "^18.3.12", "@types/react-dom": "^18.3.0", "@types/swagger-ui-react": "^4.18.3", "@typescript-eslint/eslint-plugin": "^8.11.0", From 30d3a0b918185c6b36b3a244a74fcc82f38ba0cf Mon Sep 17 00:00:00 2001 From: Ulrik Andersen Date: Fri, 25 Oct 2024 21:28:03 +0200 Subject: [PATCH 13/15] Make sure file proxy endpoint only serves JSON or YAML Does so by parsing the file's text using the yaml library. If it is parsed correctly we return the file's text. If not we return an error. --- src/app/api/proxy/route.ts | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/app/api/proxy/route.ts b/src/app/api/proxy/route.ts index 7b96c170..4a6c4b9a 100644 --- a/src/app/api/proxy/route.ts +++ b/src/app/api/proxy/route.ts @@ -1,10 +1,12 @@ import { NextRequest, NextResponse } from "next/server" import { env, makeAPIErrorResponse, makeUnauthenticatedAPIErrorResponse } from "@/common" import { session } from "@/composition" +import { parse as parseYaml } from "yaml" const ErrorName = { MAX_FILE_SIZE_EXCEEDED: "MaxFileSizeExceededError", - TIMEOUT: "TimeoutError" + TIMEOUT: "TimeoutError", + NOT_JSON_OR_YAML: "NotJsonOrYamlError", } export async function GET(req: NextRequest) { @@ -26,8 +28,9 @@ export async function GET(req: NextRequest) { const maxMegabytes = Number(env.getOrThrow("PROXY_API_MAXIMUM_FILE_SIZE_IN_MEGABYTES")) const timeoutInSeconds = Number(env.getOrThrow("PROXY_API_TIMEOUT_IN_SECONDS")) const maxBytes = maxMegabytes * 1024 * 1024 - const file = await downloadFile({ url, maxBytes, timeoutInSeconds }) - return new NextResponse(file, { status: 200 }) + const fileText = await downloadFile({ url, maxBytes, timeoutInSeconds }) + checkIfJsonOrYaml(fileText) + return new NextResponse(fileText, { status: 200 }) } catch (error) { if (error instanceof Error == false) { return makeAPIErrorResponse(500, "An unknown error occurred.") @@ -36,6 +39,8 @@ export async function GET(req: NextRequest) { return makeAPIErrorResponse(413, "The operation was aborted.") } else if (error.name === ErrorName.TIMEOUT) { return makeAPIErrorResponse(408, "The operation timed out.") + } else if (error.name === ErrorName.NOT_JSON_OR_YAML) { + return makeAPIErrorResponse(400, "Url does not point to a JSON or YAML file.") } else { return makeAPIErrorResponse(500, error.message) } @@ -46,7 +51,7 @@ async function downloadFile(params: { url: URL, maxBytes: number, timeoutInSeconds: number -}): Promise { +}): Promise { const { url, maxBytes, timeoutInSeconds } = params const abortController = new AbortController() const timeoutSignal = AbortSignal.timeout(timeoutInSeconds * 1000) @@ -80,5 +85,18 @@ async function downloadFile(params: { error.name = ErrorName.MAX_FILE_SIZE_EXCEEDED throw error } - return new Blob(chunks) + const blob = new Blob(chunks) + const arrayBuffer = await blob.arrayBuffer() + const decoder = new TextDecoder() + return decoder.decode(arrayBuffer) +} + +function checkIfJsonOrYaml(fileText: string) { + try { + parseYaml(fileText) // will also parse JSON as it is a subset of YAML + } catch { + const error = new Error("File is not JSON or YAML") + error.name = ErrorName.NOT_JSON_OR_YAML + throw error + } } From 50e9d9b5c83b268b8ca46f5f3b5e0f83e8dbc883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=2E=20St=C3=B8vring?= Date: Mon, 28 Oct 2024 09:35:12 +0100 Subject: [PATCH 14/15] Update run-unit-tests.yml --- .github/workflows/run-unit-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-unit-tests.yml b/.github/workflows/run-unit-tests.yml index cc89eee3..67fb0b08 100644 --- a/.github/workflows/run-unit-tests.yml +++ b/.github/workflows/run-unit-tests.yml @@ -15,7 +15,7 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - name: Setup Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: 20 - name: Install Dependencies From ef3bcc21a496fc6e02bdc3a6329b9da339121e26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=2E=20St=C3=B8vring?= Date: Mon, 28 Oct 2024 09:35:49 +0100 Subject: [PATCH 15/15] Update build.yml --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c969f85a..d350b2e1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,7 +15,7 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - name: Setup Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: 20 - name: Setup Environment