Enhance authorization and authentication handling by optimizing state synchronization from middleware cache, implementing error handling in custom auth, and adding admin audit and system logs pages with filtering and real-time updates.

This commit is contained in:
2025-07-09 13:00:01 -04:00
parent 36048dfed1
commit da9ab99519
6 changed files with 954 additions and 51 deletions

View File

@@ -93,30 +93,34 @@ export const useAuthorization = () => {
// Initialize immediately (both client and server)
initializeAuth();
// Watch for changes in payload data and reinitialize
// Watch for changes in payload data (optimized to prevent loops)
if (process.client) {
let watcherTimeout: NodeJS.Timeout | null = null;
watch(
() => nuxtApp.payload?.data?.authState,
(newAuthState) => {
if (newAuthState && typeof newAuthState === 'object') {
console.log('[useAuthorization] Auth state updated, reinitializing...');
hasInitialized.value = false; // Force re-initialization
initializeAuth();
(newAuthState, oldAuthState) => {
// Only update if the auth state actually changed
if (newAuthState && typeof newAuthState === 'object' && newAuthState !== oldAuthState) {
// Debounce to prevent rapid re-initialization
if (watcherTimeout) clearTimeout(watcherTimeout);
watcherTimeout = setTimeout(() => {
console.log('[useAuthorization] Auth state updated, syncing...');
// Direct sync instead of full re-initialization
authState.user = newAuthState.user || null;
authState.authenticated = newAuthState.authenticated || false;
authState.groups = Array.isArray(newAuthState.groups) ? newAuthState.groups : [];
if (!hasInitialized.value) {
hasInitialized.value = true;
isLoading.value = false;
}
}, 100); // 100ms debounce
}
},
{ immediate: true, deep: true }
);
// Also watch for session cache updates
watch(
() => nuxtApp.payload?.data?.['auth:session:cache'],
(newSessionCache) => {
if (newSessionCache && typeof newSessionCache === 'object' && !hasInitialized.value) {
console.log('[useAuthorization] Session cache updated, initializing...');
initializeAuth();
}
},
{ immediate: true, deep: true }
{ immediate: false, deep: false }
);
}

View File

@@ -16,42 +16,62 @@ export const useCustomAuth = () => {
const authenticated = ref(false)
const loading = ref(true)
const refreshing = ref(false)
const retryCount = ref(0)
const maxRetries = 3
// Check authentication status with retry logic
const checkAuth = async (skipRetry = false) => {
// Get auth state from middleware cache (no API calls!)
const syncFromCache = () => {
try {
loading.value = true
const data = await $fetch<AuthState>('/api/auth/session', {
retry: skipRetry ? 0 : 2,
retryDelay: 1000
})
user.value = data.user
authenticated.value = data.authenticated
retryCount.value = 0 // Reset retry count on success
const nuxtApp = useNuxtApp()
console.log('[CUSTOM_AUTH] Session check result:', {
authenticated: data.authenticated,
userId: data.user?.id
})
} catch (error) {
console.error('[CUSTOM_AUTH] Session check failed:', error)
// If it's a network error and we haven't exceeded retry limit, try refresh
if (!skipRetry && retryCount.value < maxRetries && (error as any)?.status >= 500) {
retryCount.value++
console.log(`[CUSTOM_AUTH] Retrying session check (${retryCount.value}/${maxRetries})...`)
// Try to get from auth state cache first
const authState = nuxtApp.payload?.data?.authState
if (authState && typeof authState === 'object') {
user.value = authState.user || null
authenticated.value = authState.authenticated || false
loading.value = false
// Wait a bit before retrying
await new Promise(resolve => setTimeout(resolve, 1000 * retryCount.value))
return checkAuth(false)
console.log('[CUSTOM_AUTH] Session synced from cache:', {
authenticated: authenticated.value,
userId: user.value?.id
})
return true
}
// Fallback to session cache
const sessionCache = nuxtApp.payload?.data?.['auth:session:cache']
if (sessionCache && typeof sessionCache === 'object') {
user.value = sessionCache.user || null
authenticated.value = sessionCache.authenticated || false
loading.value = false
console.log('[CUSTOM_AUTH] Session synced from session cache:', {
authenticated: authenticated.value,
userId: user.value?.id
})
return true
}
// No cache available
console.log('[CUSTOM_AUTH] No cache available, setting defaults')
user.value = null
authenticated.value = false
} finally {
loading.value = false
return false
} catch (error) {
console.error('[CUSTOM_AUTH] Error syncing from cache:', error)
user.value = null
authenticated.value = false
loading.value = false
return false
}
}
// Simple check auth that only uses cache
const checkAuth = async (skipRetry = false) => {
loading.value = true
const synced = syncFromCache()
if (!synced) {
console.warn('[CUSTOM_AUTH] No auth cache available, user may need to refresh')
}
}
@@ -133,6 +153,23 @@ export const useCustomAuth = () => {
checkAuth()
})
// Watch for auth state changes in the cache (client-side only)
if (process.client) {
watch(
() => {
const nuxtApp = useNuxtApp()
return nuxtApp.payload?.data?.authState
},
(newAuthState) => {
if (newAuthState && typeof newAuthState === 'object') {
console.log('[CUSTOM_AUTH] Auth state changed, syncing from cache')
syncFromCache()
}
},
{ deep: false }
)
}
return {
user: readonly(user),
authenticated: readonly(authenticated),