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

This commit is contained in:
Dmitry 2025-12-12 00:19:32 +03:00
parent 0485a35269
commit 9ca6d9ea4f
3 changed files with 65 additions and 7 deletions

View file

@ -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)
}

View file

@ -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,

View file

@ -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 ');