feat: enhance login process with session data retrieval and role extraction
Build And Push Image / docker (push) Successful in 3m5s
Details
Build And Push Image / docker (push) Successful in 3m5s
Details
This commit is contained in:
parent
05b8d97e22
commit
1b2ce79919
|
|
@ -50,15 +50,23 @@ export const useAuth = () => {
|
||||||
|
|
||||||
console.log('✅ Login response received:', response);
|
console.log('✅ Login response received:', response);
|
||||||
|
|
||||||
if (response.success && response.user) {
|
if (response.success) {
|
||||||
user.value = response.user;
|
// After successful login, get the user data from the session
|
||||||
console.log('👤 User set in composable:', user.value);
|
console.log('🔄 Getting user data from session...');
|
||||||
|
const sessionSuccess = await checkAuth();
|
||||||
|
|
||||||
|
if (sessionSuccess) {
|
||||||
|
console.log('👤 User data retrieved from session:', user.value);
|
||||||
|
|
||||||
// Redirect to dashboard or intended page
|
// Redirect to dashboard or intended page
|
||||||
console.log('🔄 Redirecting to:', response.redirectTo || '/dashboard');
|
console.log('🔄 Redirecting to:', response.redirectTo || '/dashboard');
|
||||||
await navigateTo(response.redirectTo || '/dashboard');
|
await navigateTo(response.redirectTo || '/dashboard');
|
||||||
|
|
||||||
return { success: true };
|
return { success: true };
|
||||||
|
} else {
|
||||||
|
console.warn('❌ Failed to get user data from session after login');
|
||||||
|
return { success: false, error: 'Login succeeded but failed to get user data' };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.warn('❌ Login response indicates failure:', response);
|
console.warn('❌ Login response indicates failure:', response);
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ export default defineEventHandler(async (event) => {
|
||||||
client_secret: config.keycloak.clientSecret,
|
client_secret: config.keycloak.clientSecret,
|
||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
scope: 'openid email profile'
|
scope: 'openid email profile roles'
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -180,6 +180,17 @@ export default defineEventHandler(async (event) => {
|
||||||
const tokens = await tokenResponse.json();
|
const tokens = await tokenResponse.json();
|
||||||
console.log('✅ Token exchange successful');
|
console.log('✅ Token exchange successful');
|
||||||
|
|
||||||
|
// Decode the access token to see what's inside
|
||||||
|
let tokenPayload = null;
|
||||||
|
try {
|
||||||
|
const tokenParts = tokens.access_token.split('.');
|
||||||
|
const payload = JSON.parse(Buffer.from(tokenParts[1], 'base64').toString());
|
||||||
|
tokenPayload = payload;
|
||||||
|
console.log('🔍 Access token payload:', JSON.stringify(payload, null, 2));
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('⚠️ Could not decode access token:', err);
|
||||||
|
}
|
||||||
|
|
||||||
// Get user info from Keycloak
|
// Get user info from Keycloak
|
||||||
const userResponse = await fetch(`${config.keycloak.issuer}/protocol/openid-connect/userinfo`, {
|
const userResponse = await fetch(`${config.keycloak.issuer}/protocol/openid-connect/userinfo`, {
|
||||||
headers: {
|
headers: {
|
||||||
|
|
@ -197,19 +208,74 @@ export default defineEventHandler(async (event) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const userInfo = await userResponse.json();
|
const userInfo = await userResponse.json();
|
||||||
console.log('✅ User info retrieved:', {
|
console.log('✅ User info retrieved:', JSON.stringify(userInfo, null, 2));
|
||||||
sub: userInfo.sub,
|
|
||||||
email: userInfo.email,
|
// Extract groups/roles from multiple possible locations
|
||||||
name: userInfo.name
|
const extractGroups = (tokenPayload: any, userInfo: any): string[] => {
|
||||||
|
const allGroups: string[] = [];
|
||||||
|
|
||||||
|
// Check userInfo for groups (from userinfo endpoint)
|
||||||
|
if (userInfo.groups && Array.isArray(userInfo.groups)) {
|
||||||
|
allGroups.push(...userInfo.groups);
|
||||||
|
console.log('📋 Found groups in userInfo.groups:', userInfo.groups);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check userInfo for roles
|
||||||
|
if (userInfo.roles && Array.isArray(userInfo.roles)) {
|
||||||
|
allGroups.push(...userInfo.roles);
|
||||||
|
console.log('📋 Found roles in userInfo.roles:', userInfo.roles);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check token payload for realm_access.roles
|
||||||
|
if (tokenPayload?.realm_access?.roles && Array.isArray(tokenPayload.realm_access.roles)) {
|
||||||
|
allGroups.push(...tokenPayload.realm_access.roles);
|
||||||
|
console.log('📋 Found roles in token realm_access.roles:', tokenPayload.realm_access.roles);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check token payload for resource_access roles
|
||||||
|
if (tokenPayload?.resource_access) {
|
||||||
|
Object.keys(tokenPayload.resource_access).forEach(clientId => {
|
||||||
|
const clientRoles = tokenPayload.resource_access[clientId]?.roles;
|
||||||
|
if (clientRoles && Array.isArray(clientRoles)) {
|
||||||
|
allGroups.push(...clientRoles);
|
||||||
|
console.log(`📋 Found roles in token resource_access.${clientId}.roles:`, clientRoles);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check token payload for groups claim
|
||||||
|
if (tokenPayload?.groups && Array.isArray(tokenPayload.groups)) {
|
||||||
|
allGroups.push(...tokenPayload.groups);
|
||||||
|
console.log('📋 Found groups in token.groups:', tokenPayload.groups);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove duplicates and filter out default Keycloak roles
|
||||||
|
const uniqueGroups = [...new Set(allGroups)].filter(group =>
|
||||||
|
!['default-roles-monacousa', 'offline_access', 'uma_authorization'].includes(group)
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log('📋 Final extracted groups:', uniqueGroups);
|
||||||
|
return uniqueGroups;
|
||||||
|
};
|
||||||
|
|
||||||
// Tier determination logic - admin > board > user priority
|
// Tier determination logic - admin > board > user priority
|
||||||
const determineTier = (groups: string[]): 'user' | 'board' | 'admin' => {
|
const determineTier = (groups: string[]): 'user' | 'board' | 'admin' => {
|
||||||
if (groups.includes('admin')) return 'admin';
|
console.log('🎯 Determining tier from groups:', groups);
|
||||||
if (groups.includes('board')) return 'board';
|
if (groups.includes('admin')) {
|
||||||
|
console.log('🎯 User has admin tier');
|
||||||
|
return 'admin';
|
||||||
|
}
|
||||||
|
if (groups.includes('board')) {
|
||||||
|
console.log('🎯 User has board tier');
|
||||||
|
return 'board';
|
||||||
|
}
|
||||||
|
console.log('🎯 User has default user tier');
|
||||||
return 'user'; // Default tier
|
return 'user'; // Default tier
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Extract groups from all possible sources
|
||||||
|
const extractedGroups = extractGroups(tokenPayload, userInfo);
|
||||||
|
|
||||||
// Create session data with extended expiry if remember me
|
// Create session data with extended expiry if remember me
|
||||||
const sessionData = {
|
const sessionData = {
|
||||||
user: {
|
user: {
|
||||||
|
|
@ -219,8 +285,8 @@ export default defineEventHandler(async (event) => {
|
||||||
firstName: userInfo.given_name,
|
firstName: userInfo.given_name,
|
||||||
lastName: userInfo.family_name,
|
lastName: userInfo.family_name,
|
||||||
username: userInfo.preferred_username || username,
|
username: userInfo.preferred_username || username,
|
||||||
tier: determineTier(userInfo.groups || []),
|
tier: determineTier(extractedGroups),
|
||||||
groups: userInfo.groups || ['user']
|
groups: extractedGroups.length > 0 ? extractedGroups : ['user']
|
||||||
},
|
},
|
||||||
tokens: {
|
tokens: {
|
||||||
accessToken: tokens.access_token,
|
accessToken: tokens.access_token,
|
||||||
|
|
@ -259,9 +325,9 @@ export default defineEventHandler(async (event) => {
|
||||||
// Ensure we return a proper response with status
|
// Ensure we return a proper response with status
|
||||||
setResponseStatus(event, 200);
|
setResponseStatus(event, 200);
|
||||||
|
|
||||||
|
// Return a minimal response to prevent 502 errors
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
user: sessionData.user,
|
|
||||||
redirectTo: '/dashboard'
|
redirectTo: '/dashboard'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue