Fix jwt-token

This commit is contained in:
2025-09-19 07:33:23 +02:00
parent a575e39970
commit f98fd04191
3 changed files with 100 additions and 20 deletions

View File

@@ -49,13 +49,55 @@ api.interceptors.request.use(
api.interceptors.response.use( api.interceptors.response.use(
(response) => response, (response) => response,
(error) => { (error) => {
console.log('🚨 API Error Response:', {
status: error.response?.status,
data: error.response?.data,
config: { url: error.config?.url, method: error.config?.method }
});
if (error.response?.status === 401 || error.response?.status === 403) { if (error.response?.status === 401 || error.response?.status === 403) {
// Check if it's a token-related error const errorData = error.response.data;
const errorMessage = error.response?.data?.message || ''; const errorCode = errorData?.errorCode || errorData?.error;
if (errorMessage.includes('token') || errorMessage.includes('expired') ||
errorMessage.includes('invalid') || errorMessage.includes('required') || // Show user-friendly error message based on error type
error.response?.status === 401) { let userMessage = errorData?.message || 'Authentication error';
console.warn('🔐 Authentication failed:', errorMessage);
// Categorize errors for better user experience
switch (errorCode) {
case 'TOKEN_EXPIRED':
userMessage = 'Your session has expired. Please log in again.';
break;
case 'INVALID_TOKEN':
userMessage = 'Invalid authentication. Please log in again.';
break;
case 'USER_NOT_FOUND':
userMessage = 'Your account was not found. Please contact support.';
break;
case 'ACCOUNT_INACTIVE':
userMessage = 'Your account has been deactivated. Please contact support.';
break;
case 'PERMISSION_DENIED':
userMessage = errorData.message; // Use the detailed permission message from backend
break;
default:
userMessage = errorData?.message || 'Authentication failed';
}
console.warn('🔐 Authentication/Authorization Error:', userMessage);
// Dispatch error event for UI notification
window.dispatchEvent(new CustomEvent('authError', {
detail: {
message: userMessage,
errorCode,
type: error.response.status === 403 ? 'permission' : 'auth',
userRole: errorData?.userRole,
requiredRoles: errorData?.requiredRoles
}
}));
// Only redirect to login for authentication errors, not permission errors
if (error.response.status === 401 || errorData?.redirectToLogin === true) {
console.warn('🔐 Redirecting to login page'); console.warn('🔐 Redirecting to login page');
// Clear authentication data // Clear authentication data

View File

@@ -26,7 +26,7 @@ api.interceptors.request.use(
api.interceptors.response.use( api.interceptors.response.use(
(response) => response, (response) => response,
(error) => { (error) => {
console.log('🚨 API Response Error:', { console.log('🚨 Management API Error:', {
status: error.response?.status, status: error.response?.status,
statusText: error.response?.statusText, statusText: error.response?.statusText,
data: error.response?.data, data: error.response?.data,
@@ -38,22 +38,45 @@ api.interceptors.response.use(
if (error.response?.status === 401 || error.response?.status === 403) { if (error.response?.status === 401 || error.response?.status === 403) {
const errorData = error.response.data; const errorData = error.response.data;
console.warn('🔐 Authentication failed:', errorData?.message || 'Unknown error'); const errorCode = errorData?.errorCode || errorData?.error;
console.log('🔐 Error details:', {
console.warn('🔐 Management Authentication Error:', {
error: errorData?.error, error: errorData?.error,
message: errorData?.message, message: errorData?.message,
errorCode: errorCode,
redirectToLogin: errorData?.redirectToLogin redirectToLogin: errorData?.redirectToLogin
}); });
// Show user-friendly error message based on error type
let userMessage = errorData?.message || 'Authentication error';
switch (errorCode) {
case 'TOKEN_EXPIRED':
userMessage = 'Your management session has expired. Please log in again.';
break;
case 'INVALID_TOKEN':
userMessage = 'Invalid management authentication. Please log in again.';
break;
case 'INSUFFICIENT_PERMISSIONS':
userMessage = errorData.message; // Use detailed message from backend
break;
default:
if (errorData?.message?.includes('management token')) {
userMessage = 'Your management session has expired. Please log in again.';
}
}
// Show error message (you can integrate with your notification system)
console.error('Management Error:', userMessage);
// Clear authentication data // Clear authentication data
console.log('🧹 Clearing authentication data...'); console.log('🧹 Clearing management authentication data...');
localStorage.removeItem('management_token') localStorage.removeItem('management_token')
localStorage.removeItem('management_user') localStorage.removeItem('management_user')
// Check if the backend indicates we should redirect to login // Only redirect to login for authentication errors, not permission errors
if (errorData?.redirectToLogin !== false) { if (error.response.status === 401 || errorData?.redirectToLogin !== false) {
console.log('🔄 Redirecting to login page...'); console.log('🔄 Redirecting to management login page...');
// Use both methods to ensure redirect works
try { try {
if (window.location.pathname !== '/login') { if (window.location.pathname !== '/login') {
console.log('🔄 Current path:', window.location.pathname, '- redirecting...'); console.log('🔄 Current path:', window.location.pathname, '- redirecting...');
@@ -63,11 +86,12 @@ api.interceptors.response.use(
} }
} catch (e) { } catch (e) {
console.error('Failed to redirect via location.href:', e); console.error('Failed to redirect via location.href:', e);
// Fallback: try replace
window.location.replace('/login'); window.location.replace('/login');
} }
} else { } else {
console.log('🚫 Redirect to login disabled by backend response'); console.log('🚫 Permission error - not redirecting to login');
// For permission errors, you might want to show a modal or toast notification
// instead of redirecting
} }
} }
return Promise.reject(error) return Promise.reject(error)

View File

@@ -67,14 +67,20 @@ async function authenticateToken(req, res, next) {
if (!user) { if (!user) {
return res.status(401).json({ return res.status(401).json({
success: false, success: false,
message: 'User not found' message: 'User account not found. Please contact support.',
error: 'USER_NOT_FOUND',
errorCode: 'USER_NOT_FOUND',
redirectToLogin: true
}); });
} }
if (!user.is_active) { if (!user.is_active) {
return res.status(401).json({ return res.status(401).json({
success: false, success: false,
message: 'User account is inactive' message: 'Your account has been deactivated. Please contact support.',
error: 'ACCOUNT_DEACTIVATED',
errorCode: 'ACCOUNT_INACTIVE',
redirectToLogin: true
}); });
} }
@@ -158,7 +164,10 @@ function requireRole(roles) {
if (!req.user) { if (!req.user) {
return res.status(401).json({ return res.status(401).json({
success: false, success: false,
message: 'Authentication required' message: 'Authentication required',
error: 'NO_AUTH',
errorCode: 'AUTH_REQUIRED',
redirectToLogin: true
}); });
} }
@@ -166,7 +175,12 @@ function requireRole(roles) {
if (!userRoles.includes(req.user.role)) { if (!userRoles.includes(req.user.role)) {
return res.status(403).json({ return res.status(403).json({
success: false, success: false,
message: 'Insufficient permissions' message: `Access denied. This action requires ${userRoles.join(' or ')} permissions, but you have ${req.user.role} permissions.`,
error: 'INSUFFICIENT_PERMISSIONS',
errorCode: 'PERMISSION_DENIED',
userRole: req.user.role,
requiredRoles: userRoles,
redirectToLogin: false // Don't redirect for permission issues
}); });
} }