(url: string, options: RequestInit = {})
| 48 | * Authorization is handled automatically via HttpOnly cookies + server.js proxy. |
| 49 | */ |
| 50 | export const fetchWithAuth = async (url: string, options: RequestInit = {}) => { |
| 51 | // Frontend pre-check: detect session expiry without hitting backend |
| 52 | if (typeof window !== "undefined") { |
| 53 | if ( |
| 54 | !authFlowState.isExplicitLogoutInProgress() && |
| 55 | hasAuthCookies() && |
| 56 | !checkSessionValid() |
| 57 | ) { |
| 58 | handleSessionExpired(); |
| 59 | throw new ApiError( |
| 60 | STATUS_CODES.TOKEN_EXPIRED, |
| 61 | "Login expired, please login again" |
| 62 | ); |
| 63 | } |
| 64 | } |
| 65 | |
| 66 | const isFormData = options.body instanceof FormData; |
| 67 | const headers = { |
| 68 | ...(isFormData ? {} : { "Content-Type": "application/json" }), |
| 69 | ...options.headers, |
| 70 | }; |
| 71 | |
| 72 | return fetchWithErrorHandling(url, { |
| 73 | ...options, |
| 74 | headers, |
| 75 | }); |
| 76 | }; |
| 77 | |
| 78 | /** |
| 79 | * Get common headers for API requests. |
no test coverage detected