From 465d429e09d607aceeb441d22ca8ed7ac009ae01 Mon Sep 17 00:00:00 2001 From: saravanakumardb1 Date: Sun, 15 Feb 2026 14:15:17 -0800 Subject: [PATCH] =?UTF-8?q?feat(platform-service):=20add=20Fastify=20onReq?= =?UTF-8?q?uest=20hook=20to=20parse=20JWT=20=E2=86=92=20req.jwtPayload?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Best-effort JWT parsing on every request (non-blocking for unauthenticated routes) - Attaches parsed payload to req.jwtPayload for downstream use by getRequestProductId() - Invalid/expired tokens silently ignored — auth-required routes handle their own validation --- services/platform-service/src/server.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/services/platform-service/src/server.ts b/services/platform-service/src/server.ts index f7c35a7b..06a01d5f 100644 --- a/services/platform-service/src/server.ts +++ b/services/platform-service/src/server.ts @@ -64,6 +64,22 @@ const app = await createServiceApp({ metrics: true, }); +// Parse JWT on every request (best-effort — doesn't block unauthenticated routes) +import { verifyToken } from './modules/auth/jwt.js'; +import type { JwtPayload } from './lib/request-context.js'; + +app.addHook('onRequest', async req => { + const auth = req.headers.authorization; + if (!auth?.startsWith('Bearer ')) return; + try { + const payload = await verifyToken(auth.slice(7)); + req.jwtPayload = payload as JwtPayload; + } catch { + // Token invalid/expired — leave jwtPayload undefined. + // Auth-required routes will handle this in their own validation. + } +}); + // Register route modules await app.register(productRoutes, { prefix: '/api' }); await app.register(authRoutes, { prefix: '/api' });