import { FastifyInstance } from 'fastify'; import fp from 'fastify-plugin'; import { UnauthorizedError } from '../utils/errors.js'; import type { JwtPayload } from '../types/auth.js'; // Extend @fastify/jwt's type system instead of decorating FastifyRequest declare module '@fastify/jwt' { interface FastifyJWT { payload: JwtPayload; } } async function authMiddleware(app: FastifyInstance): Promise { app.addHook('onRequest', async (request) => { const publicPaths = [ '/health', '/v1/auth/huawei', '/v1/auth/guest', '/v1/auth/phone', '/v1/auth/refresh', '/v1/auth/providers', '/v1/app/regions', ]; if (publicPaths.some((p) => request.url.startsWith(p))) { return; } // Skip admin routes (handled by admin-auth middleware) if (request.url.startsWith('/v1/admin')) { return; } try { await request.jwtVerify(); } catch { throw new UnauthorizedError('Invalid or expired token'); } }); } export default fp(authMiddleware);