port-nimara-client-portal/composables/useUnifiedAuth.ts

92 lines
2.7 KiB
TypeScript

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),
};
};