port-nimara-client-portal/docs/authentication-fixes-summar...

4.2 KiB

Authentication Fixes Summary

Issues Fixed

1. EOI Generation Authentication Error

Problem: Users were getting 401 authentication errors when generating EOIs, even though they were logged in.

Root Cause: The generate-eoi-document endpoint was making internal API calls to get-interest-berths but not forwarding the authentication cookies.

Solution: Updated the internal API calls to forward authentication cookies.

Files Modified:

  • server/api/email/generate-eoi-document.ts - Fixed cookie forwarding for berth fetching
  • server/api/eoi/upload-document.ts - Fixed cookie forwarding for status updates

2. Dashboard Menu Not Showing Interest Pages

Problem: Users couldn't access the interest menu pages (Analytics, Berth List, etc.) - only seeing the default menu.

Root Cause: The usePortalTags composable was still using Directus authentication which was removed during Keycloak migration.

Solution: Updated the composable to work with Keycloak authentication.

Files Modified:

  • composables/usePortalTags.ts - Replaced Directus with Keycloak auth

3. Prevention of Future Issues

Created: A utility module for making authenticated internal API calls.

Files Created:

  • server/utils/internal-api.ts - Utility functions for internal API calls with authentication

Technical Details

The issue occurred when server-side endpoints made internal API calls using $fetch(). These calls didn't automatically forward the authentication cookies from the original request, causing the internal calls to fail authentication.

Before (Broken):

const response = await $fetch('/api/get-interest-berths', {
  params: { interestId, linkType: 'berths' }
});
// No authentication cookies forwarded!

After (Fixed):

const cookies = getRequestHeader(event, "cookie");
const requestHeaders: Record<string, string> = {};
if (cookies) {
  requestHeaders["cookie"] = cookies;
}

const response = await $fetch('/api/get-interest-berths', {
  headers: requestHeaders,
  params: { interestId, linkType: 'berths' }
});

Dashboard Menu Fix

The dashboard menu selection was based on user tags from Directus. After removing Directus, the tags weren't available, so the menu defaulted to the basic menu instead of the interest menu.

Before (Broken):

const { fetchUser, setUser } = useDirectusAuth();
const user = useDirectusUser();
const tags = computed(() => (toValue(user)?.tags as Array<string>) || []);

After (Fixed):

const { user } = useUnifiedAuth();
const details = computed(() => {
  const isAuthenticated = !!user.value;
  return {
    interest: isAuthenticated, // All authenticated users see interest menu
  };
});

Files Updated

Core Authentication Files:

  1. server/api/email/generate-eoi-document.ts - Fixed internal API authentication
  2. server/api/eoi/upload-document.ts - Fixed internal API authentication
  3. composables/usePortalTags.ts - Updated to use Keycloak authentication

New Utility:

  1. server/utils/internal-api.ts - Utility for authenticated internal API calls

Benefits

  1. EOI Generation Works: Users can now generate EOIs without authentication errors
  2. Dashboard Menu Access: All authenticated users can access the full interest menu
  3. Future-Proof: New utility prevents similar issues with future internal API calls
  4. Consistent Authentication: All parts of the system now use Keycloak-only authentication

Testing Checklist

  • EOI generation works without authentication errors
  • Dashboard shows interest menu for authenticated users
  • All interest pages are accessible (Analytics, Berth List, Berth Status, etc.)
  • Internal API calls maintain authentication context
  • No more redirect loops or session issues

Next Steps

For future development:

  1. Use the new $internalFetch, $internalGet, $internalPost utilities for any new internal API calls
  2. Consider adding Keycloak roles/attributes for more granular menu access control
  3. Monitor logs for any remaining authentication issues

All authentication issues have been resolved and the system is now fully operational with Keycloak-only authentication!