import { defineGraphqlServerOptions } from "nuxt-graphql-middleware/server-options"; import { jwtDecode } from "jwt-decode"; import type { LoginRootMutation, UserSwitchToRootMutation } from "#graphql-operations"; interface DecodedToken { exp: number; } async function refreshAuthToken(refreshToken: string): Promise { const refreshResponse = await useGraphqlMutation("refreshJwtAuthToken", { refreshToken }); return refreshResponse.data?.refreshJwtAuthToken?.authToken || null; } export default defineGraphqlServerOptions({ async serverFetchOptions(event) { const headers = { Cookie: getRequestHeader(event, "cookie") || "", }; const session = await getUserSession(event); if (!session?.secure?.authToken) return { headers }; const decoded = jwtDecode(session.secure.authToken); const isExpired = decoded.exp * 1000 < Date.now(); if (isExpired) { const newToken = await refreshAuthToken(session.secure.refreshToken); if (newToken) { session.secure.authToken = newToken; await setUserSession(event, session); } } return { headers: { ...headers, Authorization: `Bearer ${session.secure.authToken}` } }; }, onServerResponse(event, response, _operation, operationName) { // Handle login mutation if (operationName === "login") { const loginData = response._data as LoginRootMutation; if (loginData?.login) { const { authToken, refreshToken, user } = loginData.login; setUserSession(event, { user: { id: user?.id, email: user?.email, }, secure: { authToken, refreshToken, }, }); } } // Handle user switch mutations if (operationName === "userSwitchTo") { const switchData = response._data as UserSwitchToRootMutation; if (switchData?.userSwitchTo?.authToken) { const { authToken, refreshToken, user } = switchData.userSwitchTo; setUserSession(event, { user: { id: user?.id, email: user?.email, }, secure: { authToken, refreshToken, }, }); } } // Return the original response data return response._data!; }, });