/** * 🌐 Global API Plugin — 401 Unauthorized Interceptor * * This Nuxt plugin wraps the global `$fetch` to intercept 401 responses. * When a 401 is detected, it: * 1. Calls the auth store's logout() method (clears tokens) * 2. Redirects to /login * * This fixes the P0 bug where expired tokens did not force a logout on page reload. */ import { defineNuxtPlugin, navigateTo, useCookie } from '#app' import { useAuthStore } from '~/stores/auth' export default defineNuxtPlugin(() => { // We hook into the global $fetch via onResponse interceptor // Nuxt's $fetch is built on ofetch which supports interceptors const originalFetch = globalThis.fetch // Override global fetch to intercept 401 responses globalThis.fetch = async (input: RequestInfo | URL, init?: RequestInit) => { const response = await originalFetch(input, init) // Intercept 401 Unauthorized if (response.status === 401) { // Avoid intercepting login endpoint itself (would cause redirect loops) const url = typeof input === 'string' ? input : (input instanceof URL ? input.href : input.url) if (url.includes('/auth/login') || url.includes('/auth/refresh')) { return response } // Clear auth state try { const authStore = useAuthStore() authStore.logout() } catch { // Fallback: manually clear the cookie const tokenCookie = useCookie('access_token') tokenCookie.value = null } // Redirect to login if (process.client) { // Use window.location for hard redirect to ensure full state reset window.location.href = '/login' } else { await navigateTo('/login') } } return response } })