diff --git a/app.vue b/app.vue
index 7040953..5ac3830 100644
--- a/app.vue
+++ b/app.vue
@@ -1,5 +1,7 @@
-
+
+
+
diff --git a/docs/404-and-session-fixes.md b/docs/404-and-session-fixes.md
new file mode 100644
index 0000000..54a4eef
--- /dev/null
+++ b/docs/404-and-session-fixes.md
@@ -0,0 +1,100 @@
+# 404 and Session Expiration Fixes
+
+## Issues Addressed
+
+1. **404 Error on Expenses Page** - The expenses page was returning a 404 error
+2. **Session Expiration After 404** - Users were getting logged out after encountering the 404 error
+
+## Root Cause Analysis
+
+### 404 Error Cause
+- The expenses page was missing the authorization middleware configuration
+- The dashboard layout referenced in the page metadata didn't exist
+- Nuxt wasn't properly configured to use layouts
+
+### Session Expiration Cause
+- The authentication middleware was incorrectly clearing the session cache on ALL errors (including 404s)
+- This caused a valid session to be invalidated when encountering any page error
+
+## Fixes Implemented
+
+### 1. Fixed Expenses Page Metadata
+**File**: `pages/dashboard/expenses.vue`
+
+Added proper middleware configuration:
+```javascript
+definePageMeta({
+ middleware: ['authentication', 'authorization'],
+ layout: 'dashboard',
+ roles: ['sales', 'admin']
+});
+```
+
+This ensures:
+- Authentication is checked first
+- Authorization checks for sales/admin roles
+- Proper layout is applied
+
+### 2. Fixed Authentication Middleware
+**File**: `middleware/authentication.ts`
+
+Updated error handling to only clear cache on actual auth errors:
+```javascript
+onResponseError({ response }) {
+ // Clear cache only on actual auth errors, not 404s or other errors
+ if (response.status === 401) {
+ console.log('[MIDDLEWARE] Unauthorized error detected, clearing cache')
+ sessionManager.clearCache();
+ delete nuxtApp.payload.data?.authState;
+ } else if (response.status === 403) {
+ console.log('[MIDDLEWARE] Forbidden error detected, partial cache clear')
+ // Don't clear cache on 403 as user is authenticated but lacks permissions
+ }
+ // Ignore 404s and other errors - they're not authentication issues
+}
+```
+
+### 3. Enabled Layout Support
+**File**: `app.vue`
+
+Updated to support layouts:
+```vue
+
+
+
+
+
+
+
+```
+
+### 4. Created Dashboard Layout
+**File**: `layouts/dashboard.vue`
+
+Created a full dashboard layout with:
+- Navigation drawer with role-based menu items
+- App bar showing user info and role badges
+- Proper logout functionality
+- Responsive design with rail mode
+
+## Expected Results
+
+1. **Expenses page should now load properly** for users with sales or admin roles
+2. **404 errors won't cause session expiration** - only actual authentication failures (401) will clear the session
+3. **Better error handling** - 403 errors (insufficient permissions) will redirect to dashboard with a message instead of logging out
+4. **Consistent layout** across all dashboard pages
+
+## Testing Steps
+
+1. Log in with a user that has sales or admin role
+2. Navigate to `/dashboard/expenses`
+3. Verify the page loads without 404
+4. If you don't have the required role, you should be redirected to dashboard with an error message (not logged out)
+5. Try navigating to a non-existent page - you should get a 404 but remain logged in
+
+## Additional Improvements
+
+- The authorization middleware now stores error messages that are displayed via toast
+- The dashboard layout shows the current user and their role
+- Navigation menu dynamically shows/hides items based on user roles
+- Session validation continues to work with the 3-minute cache + jitter to prevent race conditions
diff --git a/layouts/dashboard.vue b/layouts/dashboard.vue
new file mode 100644
index 0000000..096cfde
--- /dev/null
+++ b/layouts/dashboard.vue
@@ -0,0 +1,183 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ pageTitle }}
+
+
+
+
+ mdi-account
+ {{ authState.user.name || authState.user.email }}
+
+
+
+ Admin
+
+
+
+ Sales
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/middleware/authentication.ts b/middleware/authentication.ts
index 944f23c..9e196a2 100644
--- a/middleware/authentication.ts
+++ b/middleware/authentication.ts
@@ -45,12 +45,16 @@ export default defineNuxtRouteMiddleware(async (to) => {
console.log(`[MIDDLEWARE] Retrying auth check (attempt ${retries + 1})`)
},
onResponseError({ response }) {
- // Clear cache on auth errors
- if (response.status === 401 || response.status === 403) {
- console.log('[MIDDLEWARE] Auth error detected, clearing cache')
+ // Clear cache only on actual auth errors, not 404s or other errors
+ if (response.status === 401) {
+ console.log('[MIDDLEWARE] Unauthorized error detected, clearing cache')
sessionManager.clearCache();
delete nuxtApp.payload.data?.authState;
+ } else if (response.status === 403) {
+ console.log('[MIDDLEWARE] Forbidden error detected, partial cache clear')
+ // Don't clear cache on 403 as user is authenticated but lacks permissions
}
+ // Ignore 404s and other errors - they're not authentication issues
}
}) as any;
diff --git a/pages/dashboard/expenses.vue b/pages/dashboard/expenses.vue
index c33f7ed..ef33374 100644
--- a/pages/dashboard/expenses.vue
+++ b/pages/dashboard/expenses.vue
@@ -346,8 +346,9 @@ const ExpenseCreateModal = defineAsyncComponent(() => import('@/components/Expen
// Page meta
definePageMeta({
- middleware: ['authentication'],
- layout: 'dashboard'
+ middleware: ['authentication', 'authorization'],
+ layout: 'dashboard',
+ roles: ['sales', 'admin']
});
useHead({