bearer
Some checks are pending
Backend CI / test (push) Waiting to run
Backend CI / build (push) Blocked by required conditions
Deploy Admin Panel / Deploy Admin Panel (push) Waiting to run
Deploy Admin Panel / Admin Panel Verification (push) Blocked by required conditions
Deploy Mnemo Cards / Deploy Backend (push) Waiting to run
Deploy Mnemo Cards / Deploy Web App (push) Blocked by required conditions
Deploy Mnemo Cards / Final Verification (push) Blocked by required conditions
Some checks are pending
Backend CI / test (push) Waiting to run
Backend CI / build (push) Blocked by required conditions
Deploy Admin Panel / Deploy Admin Panel (push) Waiting to run
Deploy Admin Panel / Admin Panel Verification (push) Blocked by required conditions
Deploy Mnemo Cards / Deploy Backend (push) Waiting to run
Deploy Mnemo Cards / Deploy Web App (push) Blocked by required conditions
Deploy Mnemo Cards / Final Verification (push) Blocked by required conditions
This commit is contained in:
parent
0485a35269
commit
9ca6d9ea4f
3 changed files with 65 additions and 7 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import axios from 'axios'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
|
||||
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'https://api.mnemo-cards.online'
|
||||
|
||||
|
|
@ -24,29 +25,72 @@ export const adminApiClient = axios.create({
|
|||
// Request interceptor to add auth token
|
||||
const addAuthToken = (config: any) => {
|
||||
const token = localStorage.getItem('admin_token')
|
||||
const isPublicAuthEndpoint =
|
||||
config.url?.includes('/admin/auth/request-code') ||
|
||||
config.url?.includes('/admin/auth/verify-code') ||
|
||||
config.url?.includes('/admin/auth/code-status')
|
||||
|
||||
if (token && token.trim()) {
|
||||
// Ensure headers object exists
|
||||
if (!config.headers) {
|
||||
config.headers = {}
|
||||
}
|
||||
config.headers.Authorization = `Bearer ${token.trim()}`
|
||||
const trimmedToken = token.trim()
|
||||
// Set Authorization header - axios will normalize it to lowercase for HTTP
|
||||
// but we use the standard capitalization
|
||||
config.headers['Authorization'] = `Bearer ${trimmedToken}`
|
||||
|
||||
// Debug logging for admin endpoints
|
||||
if (!isPublicAuthEndpoint && config.url?.includes('/admin/')) {
|
||||
console.log('[API Client] Adding auth token to request:', config.url)
|
||||
console.log('[API Client] Token exists, length:', trimmedToken.length)
|
||||
console.log('[API Client] Authorization header set:', config.headers['Authorization']?.substring(0, 30) + '...')
|
||||
}
|
||||
} else {
|
||||
// Log warning if token is missing (except for public auth endpoints)
|
||||
const isPublicAuthEndpoint =
|
||||
config.url?.includes('/admin/auth/request-code') ||
|
||||
config.url?.includes('/admin/auth/verify-code')
|
||||
// Log error if token is missing (except for public auth endpoints)
|
||||
if (!isPublicAuthEndpoint) {
|
||||
console.warn('No admin token found in localStorage for request:', config.url)
|
||||
console.error('[API Client] No admin token found in localStorage for request:', config.url)
|
||||
console.error('[API Client] localStorage.getItem("admin_token"):', localStorage.getItem('admin_token'))
|
||||
console.error('[API Client] All localStorage keys:', Object.keys(localStorage))
|
||||
}
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
// Flag to prevent multiple logout calls
|
||||
let isLoggingOut = false
|
||||
|
||||
// Response interceptor for error handling
|
||||
const handleAuthError = (error: any) => {
|
||||
if (error.response?.status === 401) {
|
||||
// Check if we're already on login page
|
||||
const currentPath = window.location.pathname
|
||||
const isPublicAuthEndpoint =
|
||||
error.config?.url?.includes('/admin/auth/request-code') ||
|
||||
error.config?.url?.includes('/admin/auth/verify-code') ||
|
||||
error.config?.url?.includes('/admin/auth/code-status')
|
||||
|
||||
// Don't logout for public auth endpoints or if already on login page
|
||||
if (currentPath === '/login' || isPublicAuthEndpoint) {
|
||||
return Promise.reject(error)
|
||||
}
|
||||
|
||||
// Prevent multiple logout calls
|
||||
if (isLoggingOut) {
|
||||
return Promise.reject(error)
|
||||
}
|
||||
|
||||
isLoggingOut = true
|
||||
|
||||
// Remove token and update auth store
|
||||
// React Router will automatically redirect to /login when isAuthenticated becomes false
|
||||
localStorage.removeItem('admin_token')
|
||||
window.location.href = '/login'
|
||||
useAuthStore.getState().logout()
|
||||
|
||||
// Reset flag after a short delay to allow React Router to handle redirect
|
||||
setTimeout(() => {
|
||||
isLoggingOut = false
|
||||
}, 1000)
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,11 @@ export const useAuthStore = create<AuthStore>()(
|
|||
|
||||
// Actions
|
||||
login: (token: string, user: UserDto) => {
|
||||
console.log('[AuthStore] Saving token to localStorage, length:', token.length)
|
||||
localStorage.setItem('admin_token', token)
|
||||
// Verify it was saved
|
||||
const savedToken = localStorage.getItem('admin_token')
|
||||
console.log('[AuthStore] Token saved, verification:', savedToken ? `Token exists, length: ${savedToken.length}` : 'Token NOT found!')
|
||||
set({
|
||||
user,
|
||||
token,
|
||||
|
|
|
|||
|
|
@ -86,7 +86,17 @@ Middleware authorizeV2(UserManager userManager, JwtService jwtService) {
|
|||
);
|
||||
|
||||
// Extract Bearer token from Authorization header
|
||||
// Shelf normalizes headers to lowercase, so we check 'authorization'
|
||||
final authHeader = request.headers['authorization'];
|
||||
|
||||
// Debug logging for admin endpoints
|
||||
if (normalizedPath.startsWith('/admin/')) {
|
||||
print('[AUTH DEBUG] Path: $normalizedPath');
|
||||
print('[AUTH DEBUG] All headers: ${request.headers}');
|
||||
print('[AUTH DEBUG] Authorization header: $authHeader');
|
||||
print('[AUTH DEBUG] Authorization header type: ${authHeader.runtimeType}');
|
||||
}
|
||||
|
||||
final hasBearerToken =
|
||||
authHeader != null && authHeader.startsWith('Bearer ');
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue