diff --git a/docker-compose.yml b/docker-compose.yml index 1fd21dc..dd2300a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -89,6 +89,8 @@ services: KEYCLOAK_CLIENT_ID: "workclub-app" KEYCLOAK_CLIENT_SECRET: "dev-secret-workclub-api-change-in-production" KEYCLOAK_ISSUER: "http://localhost:8080/realms/workclub" + KEYCLOAK_ISSUER_INTERNAL: "http://keycloak:8080/realms/workclub" + NEXT_PUBLIC_KEYCLOAK_ISSUER: "http://localhost:8080/realms/workclub" ports: - "3000:3000" volumes: diff --git a/frontend/next.config.ts b/frontend/next.config.ts index cfec0b9..e34d821 100644 --- a/frontend/next.config.ts +++ b/frontend/next.config.ts @@ -3,13 +3,17 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { output: 'standalone', async rewrites() { - const apiUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:5001'; - return [ - { - source: '/api/:path*', - destination: `${apiUrl}/api/:path*`, - }, - ]; + const apiUrl = process.env.API_INTERNAL_URL || process.env.NEXT_PUBLIC_API_URL || 'http://localhost:5001'; + return { + beforeFiles: [], + afterFiles: [], + fallback: [ + { + source: '/api/:path*', + destination: `${apiUrl}/api/:path*`, + }, + ], + }; }, }; diff --git a/frontend/src/app/login/page.tsx b/frontend/src/app/login/page.tsx index 327b66f..2c91592 100644 --- a/frontend/src/app/login/page.tsx +++ b/frontend/src/app/login/page.tsx @@ -1,16 +1,17 @@ 'use client'; import { useEffect } from 'react'; -import { signIn, useSession } from 'next-auth/react'; -import { useRouter } from 'next/navigation'; -import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'; +import { signIn, signOut, useSession } from 'next-auth/react'; +import { useRouter, useSearchParams } from 'next/navigation'; +import { Card, CardHeader, CardTitle, CardContent, CardFooter } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; export default function LoginPage() { const { status } = useSession(); const router = useRouter(); + const searchParams = useSearchParams(); + const hasError = searchParams.get('error') || searchParams.get('callbackUrl'); - // Redirect to dashboard if already authenticated useEffect(() => { if (status === 'authenticated') { router.push('/dashboard'); @@ -21,17 +22,34 @@ export default function LoginPage() { signIn('keycloak', { callbackUrl: '/dashboard' }); }; + const handleSwitchAccount = () => { + const keycloakLogoutUrl = `${process.env.NEXT_PUBLIC_KEYCLOAK_ISSUER || 'http://localhost:8080/realms/workclub'}/protocol/openid-connect/logout?redirect_uri=${encodeURIComponent(window.location.origin + '/login')}`; + signOut({ redirect: false }).then(() => { + window.location.href = keycloakLogoutUrl; + }); + }; + return (
+ Having trouble? Try "Use different credentials" to clear your session. +
+Contact admin to get access to a club
+