Implement Keycloak authentication integration and unify user management
This commit is contained in:
91
composables/useUnifiedAuth.ts
Normal file
91
composables/useUnifiedAuth.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
export interface UnifiedUser {
|
||||
id: string;
|
||||
email: string;
|
||||
name: string;
|
||||
tier?: string;
|
||||
authSource: 'keycloak' | 'directus';
|
||||
raw: any;
|
||||
}
|
||||
|
||||
export const useUnifiedAuth = () => {
|
||||
// Get both auth systems
|
||||
const directusAuth = useDirectusAuth();
|
||||
const directusUser = useDirectusUser();
|
||||
const oidc = useOidc();
|
||||
|
||||
// Create unified user object
|
||||
const user = computed<UnifiedUser | null>(() => {
|
||||
// Check Keycloak user first
|
||||
if (oidc.user?.value) {
|
||||
const keycloakUser = oidc.user.value;
|
||||
// Construct name from firstName and lastName if available
|
||||
let name = keycloakUser.name;
|
||||
if (!name && (keycloakUser.given_name || keycloakUser.family_name)) {
|
||||
name = `${keycloakUser.given_name || ''} ${keycloakUser.family_name || ''}`.trim();
|
||||
} else if (!name && (keycloakUser.firstName || keycloakUser.lastName)) {
|
||||
name = `${keycloakUser.firstName || ''} ${keycloakUser.lastName || ''}`.trim();
|
||||
}
|
||||
if (!name) {
|
||||
name = keycloakUser.preferred_username || keycloakUser.email;
|
||||
}
|
||||
|
||||
return {
|
||||
id: keycloakUser.sub || keycloakUser.id,
|
||||
email: keycloakUser.email,
|
||||
name: name,
|
||||
tier: keycloakUser.tier || 'basic', // From custom Keycloak attribute
|
||||
authSource: 'keycloak',
|
||||
raw: keycloakUser
|
||||
};
|
||||
}
|
||||
|
||||
// Fall back to Directus user
|
||||
if (directusUser.value && directusUser.value.email) {
|
||||
return {
|
||||
id: directusUser.value.id,
|
||||
email: directusUser.value.email,
|
||||
name: `${directusUser.value.first_name || ''} ${directusUser.value.last_name || ''}`.trim() || directusUser.value.email,
|
||||
tier: directusUser.value.tier || 'basic', // If Directus has tier field
|
||||
authSource: 'directus',
|
||||
raw: directusUser.value
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
// Unified logout function
|
||||
const logout = async () => {
|
||||
if (user.value?.authSource === 'keycloak') {
|
||||
// Keycloak logout
|
||||
await oidc.logout();
|
||||
} else if (user.value?.authSource === 'directus') {
|
||||
// Directus logout
|
||||
await directusAuth.logout();
|
||||
await navigateTo('/login');
|
||||
}
|
||||
};
|
||||
|
||||
// Check if user is authenticated
|
||||
const isAuthenticated = computed(() => !!user.value);
|
||||
|
||||
// Get auth source
|
||||
const authSource = computed(() => user.value?.authSource);
|
||||
|
||||
// Check if user has specific tier
|
||||
const hasTier = (tier: string) => {
|
||||
return user.value?.tier === tier;
|
||||
};
|
||||
|
||||
// Check if user is admin
|
||||
const isAdmin = computed(() => hasTier('admin'));
|
||||
|
||||
return {
|
||||
user: readonly(user),
|
||||
logout,
|
||||
isAuthenticated: readonly(isAuthenticated),
|
||||
authSource: readonly(authSource),
|
||||
hasTier,
|
||||
isAdmin: readonly(isAdmin),
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user