Files
Ronni Baslund 17ffd95a70 chore(portal,operator): upgrade to Nuxt 4
Upgrade both Nuxt apps to Nuxt 4.4.6 (vue-tsc 3, TypeScript 5.6, undici 7) and add a root tsconfig.json to each app. Fix the strict-null / noUncheckedIndexedAccess errors surfaced by Nuxt 4's stricter generated tsconfig and vue-tsc 3. Drop the nuxt-oidc-auth pnpm patch (Nuxt 4 fixes the prepare:types crash natively).
2026-05-30 08:02:43 +02:00

57 lines
2.0 KiB
TypeScript

// Helper: forward a request to platform-api using the signed-in operator's
// access token. Every operator proxy route uses this — it's the only place
// we touch the encrypted session.
//
// Also propagates the originating client IP via X-Forwarded-For so the
// platform-api can record it in the audit log. Without this, the API would
// only see the operator container's IP.
import type { H3Event } from 'h3'
import { getUserSession } from 'nuxt-oidc-auth/runtime/server/utils/session.js'
const BASE = process.env.PLATFORM_API_INTERNAL_URL ?? 'http://platform-api:3001'
function originatingIp(event: H3Event): string | undefined {
// Traefik already injects X-Forwarded-For on the way in. Take the leftmost
// entry (the original client), trimming any whitespace.
const fwd = getHeader(event, 'x-forwarded-for')
if (fwd) {
const first = fwd.split(',')[0]?.trim()
if (first) return first
}
// Direct request (no proxy header) — fall back to the socket address.
return event.node.req.socket?.remoteAddress
}
export async function platformApi<T = unknown>(
event: H3Event,
path: string,
init: {
method?: string
body?: BodyInit | Record<string, unknown> | null
query?: Record<string, string | number | undefined>
} = {},
): Promise<T> {
const session = await getUserSession(event).catch(() => null)
const accessToken = (session as { accessToken?: string } | null)?.accessToken
if (!accessToken) {
throw createError({ statusCode: 401, statusMessage: 'Not signed in' })
}
const clientIp = originatingIp(event)
const headers: Record<string, string> = { Authorization: `Bearer ${accessToken}` }
if (clientIp) headers['x-forwarded-for'] = clientIp
try {
return (await $fetch(`${BASE}${path}`, {
method: (init.method as 'GET' | 'POST' | 'PATCH' | 'DELETE') ?? 'GET',
headers,
body: init.body,
query: init.query,
})) as T
} catch (err: unknown) {
const e = err as { statusCode?: number; data?: unknown }
throw createError({ statusCode: e.statusCode ?? 500, data: e.data })
}
}