diff --git a/.gitea/workflows/main.yml b/.gitea/workflows/main.yml index 117495e..c92892a 100644 --- a/.gitea/workflows/main.yml +++ b/.gitea/workflows/main.yml @@ -1,9 +1,6 @@ name: Main Build & Deploy -on: - push: - branches: - - main +on: workflow_dispatch jobs: build: @@ -44,9 +41,6 @@ jobs: name: Deploy Live runs-on: ubuntu-latest needs: build - environment: - name: production - url: https://pet.ivanch.me # adjust this URL as needed steps: - name: Recreate container diff --git a/src/services/api/error.ts b/src/services/api/error.ts index 789b349..03951af 100755 --- a/src/services/api/error.ts +++ b/src/services/api/error.ts @@ -49,4 +49,8 @@ export class ApiErrorHandler { static isClientError(error: ApiError): boolean { return error.status >= 400 && error.status < 500; } + + public static isUnauthorizedError(error: ApiError): boolean { + return error.status === 401; + } } \ No newline at end of file diff --git a/src/services/api/index.ts b/src/services/api/index.ts index 6379821..5f4f14c 100755 --- a/src/services/api/index.ts +++ b/src/services/api/index.ts @@ -3,6 +3,7 @@ import { apiConfig } from './config'; import { setupInterceptors } from './interceptors'; import { ApiErrorHandler } from './error'; import { ApiResponse, RequestOptions, ApiError } from './types'; +import { auth } from '../../config/firebase'; class ApiService { private static instance: ApiService; @@ -17,8 +18,8 @@ class ApiService { // Add request interceptor this.axiosInstance.interceptors.request.use( - (config) => { - const token = localStorage.getItem('TOKEN'); + async (config) => { + const token = await auth.currentUser?.getIdToken(); if (token) { config.headers.Authorization = `Bearer ${token}`; } @@ -28,6 +29,34 @@ class ApiService { return Promise.reject(error); } ); + + // Add response interceptor + this.axiosInstance.interceptors.response.use( + (response) => response, + async (error) => { + const originalRequest = error.config; + + // Check if error is 401 and we haven't tried to refresh token yet + if (error.response?.status === 401 && !originalRequest._retry) { + originalRequest._retry = true; + + try { + // Force token refresh + const user = auth.currentUser; + if (user) { + const newToken = await user.getIdToken(true); + originalRequest.headers.Authorization = `Bearer ${newToken}`; + localStorage.setItem('TOKEN', newToken); + return this.axiosInstance(originalRequest); + } + } catch (refreshError) { + return Promise.reject(refreshError); + } + } + + return Promise.reject(error); + } + ); } public static getInstance(): ApiService {