Add role-based authorization system with admin functionality
- Implement authorization middleware and composables for role checking - Add groups/roles support to authentication and session management - Create admin dashboard pages and API endpoints - Add audit logging utility for tracking user actions - Enhance expense page with role-based access control - Improve session caching with authorization state management
This commit is contained in:
@@ -7,7 +7,7 @@ export default defineEventHandler(async (event) => {
|
||||
|
||||
if (!oidcSessionCookie) {
|
||||
console.log('[SESSION] No OIDC session cookie found')
|
||||
return { user: null, authenticated: false }
|
||||
return { user: null, authenticated: false, groups: [] }
|
||||
}
|
||||
|
||||
console.log('[SESSION] OIDC session cookie found, parsing...')
|
||||
@@ -19,6 +19,7 @@ export default defineEventHandler(async (event) => {
|
||||
console.log('[SESSION] Session data parsed successfully:', {
|
||||
hasUser: !!sessionData.user,
|
||||
hasAccessToken: !!sessionData.accessToken,
|
||||
hasIdToken: !!sessionData.idToken,
|
||||
expiresAt: sessionData.expiresAt,
|
||||
createdAt: sessionData.createdAt,
|
||||
timeUntilExpiry: sessionData.expiresAt ? sessionData.expiresAt - Date.now() : 'unknown'
|
||||
@@ -31,7 +32,7 @@ export default defineEventHandler(async (event) => {
|
||||
domain: cookieDomain,
|
||||
path: '/'
|
||||
})
|
||||
return { user: null, authenticated: false }
|
||||
return { user: null, authenticated: false, groups: [] }
|
||||
}
|
||||
|
||||
// Validate session structure
|
||||
@@ -45,7 +46,7 @@ export default defineEventHandler(async (event) => {
|
||||
domain: cookieDomain,
|
||||
path: '/'
|
||||
})
|
||||
return { user: null, authenticated: false }
|
||||
return { user: null, authenticated: false, groups: [] }
|
||||
}
|
||||
|
||||
// Check if session is still valid
|
||||
@@ -61,13 +62,51 @@ export default defineEventHandler(async (event) => {
|
||||
domain: cookieDomain,
|
||||
path: '/'
|
||||
})
|
||||
return { user: null, authenticated: false }
|
||||
return { user: null, authenticated: false, groups: [] }
|
||||
}
|
||||
|
||||
// Extract groups from ID token
|
||||
let userGroups: string[] = [];
|
||||
if (sessionData.idToken) {
|
||||
try {
|
||||
// Parse JWT payload (base64 decode the middle section)
|
||||
const tokenParts = sessionData.idToken.split('.');
|
||||
if (tokenParts.length >= 2) {
|
||||
const payload = JSON.parse(atob(tokenParts[1]));
|
||||
userGroups = payload.groups || [];
|
||||
console.log('[SESSION] Groups extracted from token:', userGroups);
|
||||
}
|
||||
} catch (tokenError) {
|
||||
console.error('[SESSION] Failed to parse ID token:', tokenError);
|
||||
// Continue without groups - not a fatal error
|
||||
}
|
||||
}
|
||||
|
||||
// Also check access token for groups as fallback
|
||||
if (userGroups.length === 0 && sessionData.accessToken) {
|
||||
try {
|
||||
const tokenParts = sessionData.accessToken.split('.');
|
||||
if (tokenParts.length >= 2) {
|
||||
const payload = JSON.parse(atob(tokenParts[1]));
|
||||
userGroups = payload.groups || [];
|
||||
console.log('[SESSION] Groups extracted from access token:', userGroups);
|
||||
}
|
||||
} catch (tokenError) {
|
||||
console.error('[SESSION] Failed to parse access token:', tokenError);
|
||||
}
|
||||
}
|
||||
|
||||
// Default group assignment if no groups found
|
||||
if (userGroups.length === 0) {
|
||||
console.log('[SESSION] No groups found in token, assigning default "user" group');
|
||||
userGroups = ['user'];
|
||||
}
|
||||
|
||||
console.log('[SESSION] Valid session found for user:', {
|
||||
id: sessionData.user.id,
|
||||
email: sessionData.user.email,
|
||||
username: sessionData.user.username
|
||||
username: sessionData.user.username,
|
||||
groups: userGroups
|
||||
})
|
||||
|
||||
return {
|
||||
@@ -76,9 +115,11 @@ export default defineEventHandler(async (event) => {
|
||||
email: sessionData.user.email,
|
||||
username: sessionData.user.username,
|
||||
name: sessionData.user.name,
|
||||
authMethod: sessionData.user.authMethod || 'keycloak'
|
||||
authMethod: sessionData.user.authMethod || 'keycloak',
|
||||
groups: userGroups
|
||||
},
|
||||
authenticated: true
|
||||
authenticated: true,
|
||||
groups: userGroups
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[SESSION] OIDC session check error:', error)
|
||||
@@ -88,6 +129,6 @@ export default defineEventHandler(async (event) => {
|
||||
domain: cookieDomain,
|
||||
path: '/'
|
||||
})
|
||||
return { user: null, authenticated: false }
|
||||
return { user: null, authenticated: false, groups: [] }
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user