From 18303d2f5c8924c45ea622438a223d836d7234de Mon Sep 17 00:00:00 2001 From: Bruce Schultz Date: Fri, 22 May 2026 11:01:57 +0200 Subject: [PATCH 1/5] fix(jwt): patch proxy gap in fetch --- nuxt.config.ts | 12 +++++++++++- package.json | 1 + pnpm-lock.yaml | 3 +++ server/routes/flame/api/auth/[...].ts | 5 +++++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/nuxt.config.ts b/nuxt.config.ts index 9d8ad16..a27faa0 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -2,6 +2,10 @@ import { defineNuxtConfig } from "nuxt/config"; import { Flame } from "./app/assets/primevue/flame-preset"; import tailwindcss from "@tailwindcss/vite"; +import { fileURLToPath } from "node:url"; +import { join } from "node:path"; + +const projectRoot = fileURLToPath(new URL(".", import.meta.url)); export default defineNuxtConfig({ ssr: false, @@ -69,8 +73,14 @@ export default defineNuxtConfig({ "~/assets/css/preferences.css", ], + // @ts-expect-error nitro is a valid config key not fully typed in this nuxt version + nitro: { + alias: { + "node-fetch-native/proxy": join(projectRoot, "node_modules/node-fetch-native/dist/proxy.cjs"), + }, + }, + vite: { - // @ts-expect-error plugin complaint plugins: [tailwindcss()], }, diff --git a/package.json b/package.json index e2838d8..a9fe937 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "chart.js": "^4.5.1", "globals": "^15.15.0", "next-auth": "~4.21.1", + "node-fetch-native": "^1.6.7", "nuxt": "^4.4.6", "pinia": "^3.0.4", "prettier": "^3.6.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0cb5092..54f7a10 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -52,6 +52,9 @@ importers: next-auth: specifier: ~4.21.1 version: 4.21.1(patch_hash=be804a50721ec4d24d9187f1dbb3057252a47eef6275eedcc8684444349d1c1d)(next@13.5.11(@babel/core@7.29.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.97.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + node-fetch-native: + specifier: ^1.6.7 + version: 1.6.7 nuxt: specifier: ^4.4.6 version: 4.4.6(@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0))(@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0))(@parcel/watcher@2.5.6)(@types/node@25.3.0)(@vue/compiler-sfc@3.5.34)(cac@6.7.14)(db0@0.3.4)(eslint@9.26.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.31.1)(magicast@0.5.3)(optionator@0.9.4)(pinia@3.0.4(typescript@5.9.3)(vue@3.5.28(typescript@5.9.3)))(rollup-plugin-visualizer@7.0.1(rollup@4.60.4))(rollup@4.60.4)(sass@1.97.3)(srvx@0.11.15)(terser@5.47.1)(typescript@5.9.3)(vite@7.3.3(@types/node@25.3.0)(jiti@2.7.0)(lightningcss@1.31.1)(sass@1.97.3)(terser@5.47.1)(yaml@2.9.0))(yaml@2.9.0) diff --git a/server/routes/flame/api/auth/[...].ts b/server/routes/flame/api/auth/[...].ts index 306130a..22144d7 100644 --- a/server/routes/flame/api/auth/[...].ts +++ b/server/routes/flame/api/auth/[...].ts @@ -1,3 +1,4 @@ +import { createProxy } from "node-fetch-native/proxy"; import KeycloakProvider from "next-auth/providers/keycloak"; import AuthentikProvider from "next-auth/providers/authentik"; import OktaProvider from "next-auth/providers/okta"; @@ -146,12 +147,16 @@ async function refreshAccessToken(token: JWT) { const clientIssuer = process.env.NUXT_PUBLIC_IDP_ISSUER ?? "http://localhost:8080/realms/flame"; + const proxy = createProxy(); + const discovery = await fetch( `${clientIssuer}/.well-known/openid-configuration`, + { ...proxy }, ).then((r) => r.json()); const tokenEndpoint: string = discovery.token_endpoint; const response = await fetch(tokenEndpoint, { + ...proxy, headers: { "Content-Type": "application/x-www-form-urlencoded" }, method: "POST", body: new URLSearchParams({ From 5cdca6a98848129e2f2c48c45551c3c061aa8341 Mon Sep 17 00:00:00 2001 From: Bruce Schultz Date: Fri, 22 May 2026 11:05:30 +0200 Subject: [PATCH 2/5] fix(jwt): add proxy patches to all fetch calls --- server/routes/flame/api/auth/[...].ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/routes/flame/api/auth/[...].ts b/server/routes/flame/api/auth/[...].ts index 22144d7..16ed6d2 100644 --- a/server/routes/flame/api/auth/[...].ts +++ b/server/routes/flame/api/auth/[...].ts @@ -189,6 +189,7 @@ export default NuxtAuthHandler({ const signInEndpoint = `${hubAdapterApi.replace(/\/$/, "")}/events/signin`; try { await fetch(signInEndpoint, { + ...createProxy(), headers: { Authorization: `Bearer ${account.access_token}` }, method: "POST", }); @@ -203,6 +204,7 @@ export default NuxtAuthHandler({ const signOutEndpoint = `${hubAdapterApi.replace(/\/$/, "")}/events/signout`; try { await fetch(signOutEndpoint, { + ...createProxy(), headers: { Authorization: `Bearer ${token.access_token}` }, method: "POST", }); From 81a22771efe0d69a7f11b26259b55f93ef5f41c4 Mon Sep 17 00:00:00 2001 From: Bruce Schultz Date: Fri, 22 May 2026 11:59:45 +0200 Subject: [PATCH 3/5] chore: fix typing --- server/routes/flame/api/auth/[...].ts | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/server/routes/flame/api/auth/[...].ts b/server/routes/flame/api/auth/[...].ts index 16ed6d2..f36c007 100644 --- a/server/routes/flame/api/auth/[...].ts +++ b/server/routes/flame/api/auth/[...].ts @@ -4,6 +4,7 @@ import AuthentikProvider from "next-auth/providers/authentik"; import OktaProvider from "next-auth/providers/okta"; import OneLoginProvider from "next-auth/providers/onelogin"; import ZitadelProvider from "next-auth/providers/zitadel"; +import type { Account, Session, User } from "next-auth"; import type { JWT } from "next-auth/jwt"; import { NuxtAuthHandler } from "#auth"; @@ -151,12 +152,12 @@ async function refreshAccessToken(token: JWT) { const discovery = await fetch( `${clientIssuer}/.well-known/openid-configuration`, - { ...proxy }, + proxy as RequestInit, ).then((r) => r.json()); const tokenEndpoint: string = discovery.token_endpoint; const response = await fetch(tokenEndpoint, { - ...proxy, + ...(proxy as RequestInit), headers: { "Content-Type": "application/x-www-form-urlencoded" }, method: "POST", body: new URLSearchParams({ @@ -182,14 +183,14 @@ async function refreshAccessToken(token: JWT) { export default NuxtAuthHandler({ secret: useRuntimeConfig().authSecret, events: { - async signIn({ account }) { + async signIn({ account }: { account: Account | null }) { // After successful sign in const hubAdapterApi = process.env.NUXT_PUBLIC_HUB_ADAPTER_URL; if (!hubAdapterApi || !account?.access_token) return; const signInEndpoint = `${hubAdapterApi.replace(/\/$/, "")}/events/signin`; try { await fetch(signInEndpoint, { - ...createProxy(), + ...(createProxy() as RequestInit), headers: { Authorization: `Bearer ${account.access_token}` }, method: "POST", }); @@ -197,14 +198,14 @@ export default NuxtAuthHandler({ console.error("Failed to log sign-in event:", error); } }, - async signOut({ token }) { + async signOut({ token }: { session: Session; token: JWT }) { // After successful sign out const hubAdapterApi = process.env.NUXT_PUBLIC_HUB_ADAPTER_URL; if (!hubAdapterApi || !token?.access_token) return; const signOutEndpoint = `${hubAdapterApi.replace(/\/$/, "")}/events/signout`; try { await fetch(signOutEndpoint, { - ...createProxy(), + ...(createProxy() as RequestInit), headers: { Authorization: `Bearer ${token.access_token}` }, method: "POST", }); @@ -215,7 +216,7 @@ export default NuxtAuthHandler({ }, callbacks: { /* on session retrieval */ - async session({ session, token }) { + async session({ session, token }: { session: Session; token: JWT }) { return { ...session, accessToken: token.access_token, @@ -223,7 +224,15 @@ export default NuxtAuthHandler({ }; }, /* on JWT token creation or mutation */ - async jwt({ token, account, user }) { + async jwt({ + token, + account, + user, + }: { + token: JWT; + account: Account | null; + user: User; + }) { if (account && user) { if (account.type === "credentials") { // CredentialsProvider (Hub password grant): tokens live on the user object From f11f069752ca171046e6552f351b82fc5ba0d584 Mon Sep 17 00:00:00 2001 From: Bruce Schultz Date: Fri, 22 May 2026 12:11:40 +0200 Subject: [PATCH 4/5] fix(logs): remove malformed request --- app/components/analysis/logs/ContainerLogs.vue | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/components/analysis/logs/ContainerLogs.vue b/app/components/analysis/logs/ContainerLogs.vue index bc4913c..f473c4b 100644 --- a/app/components/analysis/logs/ContainerLogs.vue +++ b/app/components/analysis/logs/ContainerLogs.vue @@ -25,7 +25,7 @@ const { data: response, status, error, -} = await getAnalysisLogs(analysisId, { limit: null }); +} = await getAnalysisLogs(analysisId); const lastFetchedAt = ref(null); @@ -93,7 +93,6 @@ async function refreshLogs() { const result = await useNuxtApp() .$hubApi(`/logs/${analysisId}`, { method: "GET", - query: { limit: null }, }) .catch(() => undefined); if (result) { From e3dc7393e9f17926b4e37ed65380a10dbc4be422 Mon Sep 17 00:00:00 2001 From: Bruce Schultz Date: Fri, 22 May 2026 12:29:38 +0200 Subject: [PATCH 5/5] chore(api): update api --- app/services/hub_adapter_swagger.json | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/app/services/hub_adapter_swagger.json b/app/services/hub_adapter_swagger.json index 270d2fd..44522ed 100644 --- a/app/services/hub_adapter_swagger.json +++ b/app/services/hub_adapter_swagger.json @@ -2892,7 +2892,6 @@ } ], "description": "Maximum number of log lines to return per container", - "default": 1000, "title": "Limit" }, "description": "Maximum number of log lines to return per container" @@ -3011,9 +3010,15 @@ "in": "query", "required": false, "schema": { - "type": "integer", + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], "description": "Maximum number of log lines to return per container", - "default": 1000, "title": "Limit" }, "description": "Maximum number of log lines to return per container" @@ -3133,11 +3138,11 @@ "required": false, "schema": { "type": "integer", - "description": "Maximum number of raw log entries to return", + "description": "Maximum number of analysis groups to return", "default": 1000, "title": "Limit" }, - "description": "Maximum number of raw log entries to return" + "description": "Maximum number of analysis groups to return" } ], "responses": {