- Fix clubs attribute in Keycloak to contain only UUIDs (removed role names)
- Add defensive error handling in ClubService.GetMyClubsAsync()
- Add logging for debugging club retrieval issues
- Return empty list instead of 500 error on failures
Fixes: Admin users can now manage clubs without contact admin error
Next.js rewrites are evaluated at build time, not runtime.
The API_INTERNAL_URL was set in K8s deployment but not during
the Docker build, causing fallback to localhost:5001.
- Added ENV API_INTERNAL_URL=http://workclub-api:8080
- This ensures Next.js rewrites point to internal K8s service
The Next.js rewrites were falling back to localhost:5001 because
API_INTERNAL_URL was not set. This caused API proxy errors.
- Added API_INTERNAL_URL=http://workclub-api:8080
- This allows Next.js to proxy /api/* calls to the internal backend service
The jwt callback was only checking isAdmin during initial login when
account was present, but not on subsequent session refreshes. This caused
the admin status to be lost after the initial login.
- Moved admin status check outside of the 'if (account)' block
- Now checks isAdmin on every JWT callback when accessToken is available
- Changed api-base-url from :5001 to :30501
- Changed keycloak-url from :8080 to :30808
- Changed keycloak-authority from :8080 to :30808
The frontend was trying to connect to port 8080 which is not exposed
externally. Keycloak is accessible via NodePort 30808.
- Frontend: nodePort 3000 → 30080
- Backend: nodePort 5001 → 30501, service port 5001 → 8080
- Keycloak: nodePort 8080 → 30808
Kubernetes requires NodePort to be in range 30000-32767.
The service port (internal) and targetPort (container) remain
unchanged for compatibility with existing configurations.
- Removed localhost:3000/* from redirectUris in realm-export.json
- Removed localhost:3000 from webOrigins in realm-export.json
- Removed localhost:3000/* from post.logout.redirect.uris
- Removed localhost:3000 from keycloak-realm-import-configmap.yaml
- Updated running Keycloak instance via kcadm.sh
Only port 30080 is now configured for OAuth redirects.
- Frontend: Changed NodePort from 30080 to 3000 (matches Docker port)
- Backend: Changed NodePort from 30081 to 5001 (matches Docker port)
- Keycloak: Changed NodePort from 30082 to 8080 (matches Docker port)
- Updated ConfigMap URLs to use new ports
- Updated NEXTAUTH_URL to use port 3000
This ensures Kubernetes deployment uses the same ports as Docker Compose
for consistency across environments.
The deployment was unreachable because the Next.js server was binding
to localhost:3000 (127.0.0.1) instead of 0.0.0.0, making it only
accessible inside the Docker container.
- Added HOSTNAME=0.0.0.0 to Dockerfile build and runtime stages
- Added HOSTNAME=0.0.0.0 to docker-compose.yml for nextjs service
This allows the server to accept connections from external hosts.
The build was failing because KEYCLOAK_ISSUER and KEYCLOAK_CLIENT_ID
were undefined during the static generation phase. Added default values
that match the development configuration.
- Added fallback for KEYCLOAK_ISSUER
- Added fallback for KEYCLOAK_CLIENT_ID
The test was expecting Forbidden when no tenant context is provided,
but the middleware actually returns BadRequest when X-Tenant-Id header
is missing. Updated the test and added GetClubsCurrent_InvalidTenant_ReturnsForbidden
to properly test the Forbidden case.
- Added IssuerSigningKeyResolver to fetch JWKS directly from internal Keycloak URL
- This bypasses the localhost:8080 URLs in Keycloak's discovery document
- Ensures JWT tokens are validated against correct signing keys
- Add MetadataAddress configuration to JWT middleware for internal Docker URLs
- Add KC_HOSTNAME_ADMIN and KC_SPI_HOSTNAME_DEFAULT_ADMIN to Keycloak env
- This ensures API can fetch JWKS from Keycloak via internal Docker network
- Tests passing: 63/63
The JWT middleware needs to fetch signing keys from Keycloak before
tenant validation runs. The previous order caused signature validation
to fail because the middleware was blocking the JWKS endpoint requests.
- Moved Authentication before TenantValidationMiddleware
- Removed realm endpoint from exemption list (not needed with correct order)
- This allows JWT middleware to fetch signing keys and validate tokens
- Added JWT authentication event logging to diagnose validation failures
- Fixed docker-compose networking for API to reach Keycloak via hostname
- Debug endpoint now accessible without auth for troubleshooting
- Still investigating why claims are not populated despite token being present
- Add CORS policy to allow frontend requests from localhost:3000
- Exempt /api/debug endpoints from tenant validation
- Fix JSON parsing in realm_access claim checks
The realm_access claim in JWT is a JSON object, not a simple string.
Previous string contains check was looking for escaped quotes in wrong format.
- Parse realm_access as JSON to extract roles array
- Check if 'admin' exists in roles array
- Fallback to string contains check if JSON parsing fails
- Applied fix in RequireGlobalAdmin policy, TenantValidationMiddleware,
and ClubRoleClaimsTransformation
Fixes: Admin users getting 401 when trying to create clubs
- Add BYPASSRLS privilege to app_admin role
- Grant full schema and table access to app_admin
- Allow rls_test_user to assume app_admin role
- Fixes: permission denied for table clubs (42501)
Trust external host for Auth.js, provide missing frontend auth env/secrets, and submit a proper CSRF-backed sign-in POST so browser login reaches Keycloak reliably.
Update Keycloak probe/realm import behavior and authority config so auth services start reliably on the dev cluster, while keeping CD deployment steps aligned with the actual Kubernetes overlay behavior.