cleaning hard 2
This commit is contained in:
parent
1f39edde7b
commit
e9a0dbfc4a
@ -60,7 +60,32 @@ export const authOptions: NextAuthOptions = {
|
||||
clientSecret: process.env.KEYCLOAK_CLIENT_SECRET || "",
|
||||
issuer: process.env.KEYCLOAK_ISSUER || "",
|
||||
profile(profile: any) {
|
||||
console.log("Raw Keycloak profile:", profile);
|
||||
console.log("Raw Keycloak profile:", JSON.stringify(profile, null, 2));
|
||||
|
||||
// Try to extract all possible roles from the profile
|
||||
let roles: string[] = [];
|
||||
|
||||
// Get roles from realm_access
|
||||
if (profile.realm_access && Array.isArray(profile.realm_access.roles)) {
|
||||
roles = roles.concat(profile.realm_access.roles);
|
||||
}
|
||||
|
||||
// Get roles from resource_access
|
||||
if (profile.resource_access) {
|
||||
for (const client in profile.resource_access) {
|
||||
if (profile.resource_access[client] &&
|
||||
Array.isArray(profile.resource_access[client].roles)) {
|
||||
roles = roles.concat(profile.resource_access[client].roles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get roles from groups if available
|
||||
if (profile.groups && Array.isArray(profile.groups)) {
|
||||
roles = roles.concat(profile.groups);
|
||||
}
|
||||
|
||||
console.log("Extracted roles from profile:", roles);
|
||||
|
||||
// Just return a simple profile with required fields
|
||||
return {
|
||||
@ -71,7 +96,7 @@ export const authOptions: NextAuthOptions = {
|
||||
username: profile.preferred_username || profile.email?.split('@')[0] || '',
|
||||
first_name: profile.given_name || '',
|
||||
last_name: profile.family_name || '',
|
||||
role: profile.realm_access?.roles || ['user'],
|
||||
role: roles.length > 0 ? roles : ['user'],
|
||||
// Store raw profile data for later processing
|
||||
raw_profile: profile
|
||||
};
|
||||
@ -86,12 +111,16 @@ export const authOptions: NextAuthOptions = {
|
||||
async jwt({ token, account, profile, user }: any) {
|
||||
// Initial sign in
|
||||
if (account && account.access_token) {
|
||||
console.log("FULL USER OBJECT:", JSON.stringify(user, null, 2));
|
||||
console.log("FULL ACCOUNT OBJECT:", JSON.stringify(account, null, 2));
|
||||
|
||||
token.accessToken = account.access_token;
|
||||
token.refreshToken = account.refresh_token;
|
||||
|
||||
// Process the raw profile data if available
|
||||
if (user && user.raw_profile) {
|
||||
const rawProfile = user.raw_profile;
|
||||
console.log("RAW KEYCLOAK PROFILE:", JSON.stringify(rawProfile, null, 2));
|
||||
|
||||
// Extract roles from all possible sources
|
||||
let roles: string[] = [];
|
||||
@ -105,6 +134,9 @@ export const authOptions: NextAuthOptions = {
|
||||
// Get roles from resource_access
|
||||
if (rawProfile.resource_access) {
|
||||
const clientId = process.env.KEYCLOAK_CLIENT_ID;
|
||||
console.log("Client ID for resource access:", clientId);
|
||||
console.log("Resource access object:", JSON.stringify(rawProfile.resource_access, null, 2));
|
||||
|
||||
if (clientId &&
|
||||
rawProfile.resource_access[clientId] &&
|
||||
Array.isArray(rawProfile.resource_access[clientId].roles)) {
|
||||
@ -118,6 +150,20 @@ export const authOptions: NextAuthOptions = {
|
||||
roles = roles.concat(rawProfile.resource_access.account.roles);
|
||||
console.log("Roles from resource_access.account:", rawProfile.resource_access.account.roles);
|
||||
}
|
||||
|
||||
// Check for any roles in any client
|
||||
for (const [clientKey, clientData] of Object.entries(rawProfile.resource_access)) {
|
||||
if (clientData && Array.isArray((clientData as any).roles)) {
|
||||
console.log(`Found roles in client ${clientKey}:`, (clientData as any).roles);
|
||||
roles = roles.concat((clientData as any).roles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Look for roles in other potential locations
|
||||
if (rawProfile.groups && Array.isArray(rawProfile.groups)) {
|
||||
console.log("Found groups that might contain roles:", rawProfile.groups);
|
||||
roles = roles.concat(rawProfile.groups);
|
||||
}
|
||||
|
||||
// Clean up roles and convert to lowercase
|
||||
@ -134,10 +180,12 @@ export const authOptions: NextAuthOptions = {
|
||||
token.role = mapToApplicationRoles(finalRoles);
|
||||
console.log("Mapped application roles:", token.role);
|
||||
} else if (user && user.role) {
|
||||
console.log("Using direct user.role:", user.role);
|
||||
token.role = Array.isArray(user.role) ? user.role : [user.role];
|
||||
console.log("Using user.role directly:", token.role);
|
||||
} else {
|
||||
// Default roles if no profile data available
|
||||
console.log("No role data found in user object or profile");
|
||||
token.role = ['user'];
|
||||
console.log("Using default 'user' role only");
|
||||
}
|
||||
@ -155,6 +203,7 @@ export const authOptions: NextAuthOptions = {
|
||||
console.log("Adding default 'user' role to existing token");
|
||||
}
|
||||
|
||||
console.log("FINAL TOKEN:", JSON.stringify(token, null, 2));
|
||||
return token;
|
||||
},
|
||||
async session({ session, token }: any) {
|
||||
@ -204,36 +253,82 @@ export const authOptions: NextAuthOptions = {
|
||||
* Maps Keycloak roles to application-specific roles
|
||||
*/
|
||||
function mapToApplicationRoles(keycloakRoles: string[]): string[] {
|
||||
// Debug input
|
||||
console.log("Mapping input roles:", keycloakRoles);
|
||||
|
||||
// For development/testing, directly assign application roles based on username
|
||||
// This helps in case Keycloak isn't properly configured
|
||||
let appRoles: string[] = ['user']; // Always include 'user' role
|
||||
|
||||
// The mappings object maps Keycloak role names to application role names
|
||||
const mappings: Record<string, string[]> = {
|
||||
// Map Keycloak roles to your application's role names
|
||||
'admin': ['admin', 'dataintelligence', 'coding', 'expression', 'mediation'],
|
||||
'owner': ['admin', 'dataintelligence', 'coding', 'expression', 'mediation'],
|
||||
'cercle-admin': ['admin', 'dataintelligence', 'coding', 'expression', 'mediation'],
|
||||
'manager': ['dataintelligence', 'coding', 'expression', 'mediation'],
|
||||
'admin': ['admin', 'dataintelligence', 'coding', 'expression', 'mediation', 'entrepreneurship'],
|
||||
'owner': ['admin', 'dataintelligence', 'coding', 'expression', 'mediation', 'entrepreneurship'],
|
||||
'manager': ['dataintelligence', 'coding', 'expression', 'mediation', 'entrepreneurship'],
|
||||
'developer': ['coding', 'dataintelligence'],
|
||||
'data-scientist': ['dataintelligence'],
|
||||
'designer': ['expression'],
|
||||
'writer': ['expression'],
|
||||
'mediator': ['mediation'],
|
||||
'entrepreneur': ['entrepreneurship'],
|
||||
|
||||
// Common prefixed variants
|
||||
'role_admin': ['admin', 'dataintelligence', 'coding', 'expression', 'mediation', 'entrepreneurship'],
|
||||
'realm_admin': ['admin', 'dataintelligence', 'coding', 'expression', 'mediation', 'entrepreneurship'],
|
||||
'app_admin': ['admin', 'dataintelligence', 'coding', 'expression', 'mediation', 'entrepreneurship'],
|
||||
|
||||
// Default access roles from Keycloak
|
||||
'default-roles-cercle': ['user'],
|
||||
'uma_authorization': ['user'],
|
||||
'offline_access': ['user'],
|
||||
// Add more mappings as needed
|
||||
|
||||
// Direct mapping for flexibility
|
||||
'expression': ['expression'],
|
||||
'mediation': ['mediation'],
|
||||
'coding': ['coding'],
|
||||
'dataintelligence': ['dataintelligence'],
|
||||
'entrepreneurship': ['entrepreneurship'],
|
||||
};
|
||||
|
||||
// Map each role and flatten the result
|
||||
let appRoles: string[] = ['user']; // Always include 'user' role
|
||||
|
||||
// Try to match each role with our mappings
|
||||
for (const role of keycloakRoles) {
|
||||
const mappedRoles = mappings[role.toLowerCase()];
|
||||
if (mappedRoles) {
|
||||
appRoles = [...appRoles, ...mappedRoles];
|
||||
// Try different variations of the role name
|
||||
const normalizedRole = role.toLowerCase()
|
||||
.replace(/^role_/i, '') // Remove ROLE_ prefix
|
||||
.replace(/^realm_/i, '') // Remove REALM_ prefix
|
||||
.replace(/^app_/i, ''); // Remove APP_ prefix
|
||||
|
||||
console.log(`Processing role: ${role} -> normalized: ${normalizedRole}`);
|
||||
|
||||
// Check for direct match
|
||||
if (mappings[normalizedRole]) {
|
||||
appRoles = [...appRoles, ...mappings[normalizedRole]];
|
||||
console.log(`Mapped ${role} to: ${mappings[normalizedRole].join(', ')}`);
|
||||
}
|
||||
// Check for partial matches
|
||||
else {
|
||||
for (const [mapKey, mapRoles] of Object.entries(mappings)) {
|
||||
if (normalizedRole.includes(mapKey)) {
|
||||
appRoles = [...appRoles, ...mapRoles];
|
||||
console.log(`Partially matched ${role} with ${mapKey} to: ${mapRoles.join(', ')}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DEVELOPMENT OVERRIDE - Comment out in production
|
||||
// Assign all roles for testing
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
// Add specific development testing roles
|
||||
appRoles = ['user', 'admin', 'expression', 'mediation', 'coding', 'dataintelligence', 'entrepreneurship'];
|
||||
console.log("DEVELOPMENT MODE: Using all roles for testing");
|
||||
}
|
||||
|
||||
// Remove duplicates and return
|
||||
return [...new Set(appRoles)];
|
||||
const uniqueRoles = [...new Set(appRoles)];
|
||||
console.log("Final mapped roles:", uniqueRoles);
|
||||
return uniqueRoles;
|
||||
}
|
||||
|
||||
const handler = NextAuth(authOptions);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user