diff --git a/apps/dashboard/app/login/page.tsx b/apps/dashboard/app/login/page.tsx index f1fc9a6..54ab001 100644 --- a/apps/dashboard/app/login/page.tsx +++ b/apps/dashboard/app/login/page.tsx @@ -1,3 +1,5 @@ +import { headers } from "next/headers"; +import { redirect } from "next/navigation"; import { LoginForm } from "./login-form"; import { Card, @@ -5,8 +7,12 @@ import { CardHeader, } from "@/components/ui/card"; import { BrandLogo } from "@/components/brand-logo"; +import { auth } from "@/lib/auth"; import { getBranding } from "@/lib/branding-server"; -import { safeCallbackPath } from "@/lib/safe-callback-path"; +import { + DEFAULT_CALLBACK_PATH, + safeCallbackPath, +} from "@/lib/safe-callback-path"; export default async function Login({ searchParams, @@ -14,6 +20,14 @@ export default async function Login({ searchParams: Promise<{ callbackURL?: string }>; }) { const { callbackURL } = await searchParams; + const callbackPath = safeCallbackPath(callbackURL); + const session = await auth.api.getSession({ headers: await headers() }); + if (session) { + redirect( + callbackPath === "/login" ? DEFAULT_CALLBACK_PATH : callbackPath, + ); + } + const branding = await getBranding(); return (
@@ -22,7 +36,7 @@ export default async function Login({ - +
diff --git a/tests/e2e/specs/journey.spec.ts b/tests/e2e/specs/journey.spec.ts index 1ff8627..184aafd 100644 --- a/tests/e2e/specs/journey.spec.ts +++ b/tests/e2e/specs/journey.spec.ts @@ -161,6 +161,18 @@ test.describe.serial("Blue deployment journey", () => { expect(refreshedClaims.aud).toBeTruthy(); }); + test("@smoke authenticated users are redirected away from login", async ({ page }) => { + await loginAsAdmin(page); + + await page.goto("/login", { waitUntil: "commit" }); + await expect(page).toHaveURL(/\/sessions$/); + await expect(page.getByLabel("Email")).toHaveCount(0); + + await page.goto("/login?callbackURL=%2Fgateway", { waitUntil: "commit" }); + await expect(page).toHaveURL(/\/gateway$/); + await expect(page.getByLabel("Email")).toHaveCount(0); + }); + test("@smoke executable provisioner creates managed gateway access", async () => { const result = await runCli(home, ["gateway"]); expect(result.code, result.stderr).toBe(0);