diff --git a/frontend/src/app/login/page.tsx b/frontend/src/app/login/page.tsx index 72ebb10..12aa556 100644 --- a/frontend/src/app/login/page.tsx +++ b/frontend/src/app/login/page.tsx @@ -1,7 +1,7 @@ 'use client'; import { useEffect, Suspense } from 'react'; -import { signIn, signOut, useSession } from 'next-auth/react'; +import { 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'; @@ -18,8 +18,33 @@ function LoginContent() { } }, [status, router]); - const handleSignIn = () => { - signIn('keycloak', { callbackUrl: '/dashboard' }); + const handleSignIn = async () => { + const csrfResponse = await fetch('/api/auth/csrf'); + const csrfPayload = await csrfResponse.json() as { csrfToken?: string }; + + if (!csrfPayload.csrfToken) { + window.location.href = '/api/auth/signin?callbackUrl=%2Fdashboard'; + return; + } + + const form = document.createElement('form'); + form.method = 'POST'; + form.action = '/api/auth/signin/keycloak'; + + const csrfInput = document.createElement('input'); + csrfInput.type = 'hidden'; + csrfInput.name = 'csrfToken'; + csrfInput.value = csrfPayload.csrfToken; + form.appendChild(csrfInput); + + const callbackInput = document.createElement('input'); + callbackInput.type = 'hidden'; + callbackInput.name = 'callbackUrl'; + callbackInput.value = `${window.location.origin}/dashboard`; + form.appendChild(callbackInput); + + document.body.appendChild(form); + form.submit(); }; const handleSwitchAccount = () => { diff --git a/infra/k8s/base/frontend-deployment.yaml b/infra/k8s/base/frontend-deployment.yaml index d25925a..ce73567 100644 --- a/infra/k8s/base/frontend-deployment.yaml +++ b/infra/k8s/base/frontend-deployment.yaml @@ -62,3 +62,31 @@ spec: configMapKeyRef: name: workclub-config key: keycloak-url + - name: NEXT_PUBLIC_KEYCLOAK_ISSUER + valueFrom: + configMapKeyRef: + name: workclub-config + key: keycloak-authority + - name: NEXTAUTH_URL + value: "http://192.168.240.200:30080" + - name: AUTH_TRUST_HOST + value: "true" + - name: NEXTAUTH_SECRET + valueFrom: + secretKeyRef: + name: workclub-secrets + key: nextauth-secret + - name: KEYCLOAK_CLIENT_ID + value: "workclub-app" + - name: KEYCLOAK_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: workclub-secrets + key: keycloak-client-secret + - name: KEYCLOAK_ISSUER + valueFrom: + configMapKeyRef: + name: workclub-config + key: keycloak-authority + - name: KEYCLOAK_ISSUER_INTERNAL + value: "http://workclub-keycloak/realms/workclub" diff --git a/infra/k8s/overlays/dev/secrets.yaml b/infra/k8s/overlays/dev/secrets.yaml index afdc1c7..66c00e4 100644 --- a/infra/k8s/overlays/dev/secrets.yaml +++ b/infra/k8s/overlays/dev/secrets.yaml @@ -9,3 +9,5 @@ stringData: keycloak-db-password: "keycloakpass" keycloak-admin-username: "admin" keycloak-admin-password: "adminpassword" + keycloak-client-secret: "dev-secret-workclub-api-change-in-production" + nextauth-secret: "dev-secret-change-in-production-use-openssl-rand-base64-32"