From 70448e81864d49c85c5f25e5dfbe2219b3eeeea8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 14 Nov 2025 14:07:17 +0000 Subject: [PATCH 1/3] Initial plan From c210e45bffb5845965db798884257086c702f7a5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 14 Nov 2025 14:12:16 +0000 Subject: [PATCH 2/3] Add redirect logic to login and signup pages for logged-in users Co-authored-by: vincanger <70215737+vincanger@users.noreply.github.com> --- template/app/src/auth/LoginPage.tsx | 13 ++++++++++++- template/app/src/auth/SignupPage.tsx | 13 ++++++++++++- template/app/src/payment/stripe/webhook.ts | 4 ++-- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/template/app/src/auth/LoginPage.tsx b/template/app/src/auth/LoginPage.tsx index 4d3a02995..d74fc0842 100644 --- a/template/app/src/auth/LoginPage.tsx +++ b/template/app/src/auth/LoginPage.tsx @@ -1,8 +1,19 @@ -import { LoginForm } from "wasp/client/auth"; +import { useEffect } from "react"; +import { useNavigate } from "react-router-dom"; +import { LoginForm, useAuth } from "wasp/client/auth"; import { Link as WaspRouterLink, routes } from "wasp/client/router"; import { AuthPageLayout } from "./AuthPageLayout"; export default function Login() { + const { data: user } = useAuth(); + const navigate = useNavigate(); + + useEffect(() => { + if (user) { + navigate("/demo-app"); + } + }, [user, navigate]); + return ( diff --git a/template/app/src/auth/SignupPage.tsx b/template/app/src/auth/SignupPage.tsx index 0afa0b083..87a7f9ff0 100644 --- a/template/app/src/auth/SignupPage.tsx +++ b/template/app/src/auth/SignupPage.tsx @@ -1,8 +1,19 @@ -import { SignupForm } from "wasp/client/auth"; +import { useEffect } from "react"; +import { useNavigate } from "react-router-dom"; +import { SignupForm, useAuth } from "wasp/client/auth"; import { Link as WaspRouterLink, routes } from "wasp/client/router"; import { AuthPageLayout } from "./AuthPageLayout"; export function Signup() { + const { data: user } = useAuth(); + const navigate = useNavigate(); + + useEffect(() => { + if (user) { + navigate("/demo-app"); + } + }, [user, navigate]); + return ( diff --git a/template/app/src/payment/stripe/webhook.ts b/template/app/src/payment/stripe/webhook.ts index 44d1924d6..d0a7cd402 100644 --- a/template/app/src/payment/stripe/webhook.ts +++ b/template/app/src/payment/stripe/webhook.ts @@ -141,7 +141,7 @@ async function handleInvoicePaid( function getInvoicePriceId(invoice: Stripe.Invoice): Stripe.Price["id"] { const invoiceLineItems = invoice.lines.data; - // We only expect one line item. + // We only expect one line item. // If your workflow expects more, you should change this function to handle them. if (invoiceLineItems.length !== 1) { throw new Error("There should be exactly one line item in Stripe invoice"); @@ -204,7 +204,7 @@ function getSubscriptionPriceId( subscription: Stripe.Subscription, ): Stripe.Price["id"] { const subscriptionItems = subscription.items.data; - // We only expect one subscription item. + // We only expect one subscription item. // If your workflow expects more, you should change this function to handle them. if (subscriptionItems.length !== 1) { throw new Error( From cb03a2526b373eb738bed9d3261fe5b790edfaca Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 14 Nov 2025 14:13:11 +0000 Subject: [PATCH 3/3] Add e2e test for auth redirect behavior Co-authored-by: vincanger <70215737+vincanger@users.noreply.github.com> --- .../e2e-tests/tests/authRedirectTests.spec.ts | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 template/e2e-tests/tests/authRedirectTests.spec.ts diff --git a/template/e2e-tests/tests/authRedirectTests.spec.ts b/template/e2e-tests/tests/authRedirectTests.spec.ts new file mode 100644 index 000000000..c384eedf1 --- /dev/null +++ b/template/e2e-tests/tests/authRedirectTests.spec.ts @@ -0,0 +1,38 @@ +import { expect, test, type Page } from "@playwright/test"; +import { createRandomUser, logUserIn, signUserUp, type User } from "./utils"; + +let page: Page; +let testUser: User; + +test.describe.configure({ mode: "serial" }); + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); + testUser = createRandomUser(); + await signUserUp({ page, user: testUser }); + await logUserIn({ page, user: testUser }); +}); + +test.afterAll(async () => { + await page.close(); +}); + +test.describe("auth redirect tests", () => { + test("logged-in user visiting /login should redirect to /demo-app", async () => { + // User is already logged in from beforeAll + await page.goto("/login"); + + // Should be redirected to /demo-app + await page.waitForURL("**/demo-app", { timeout: 5000 }); + expect(page.url()).toContain("/demo-app"); + }); + + test("logged-in user visiting /signup should redirect to /demo-app", async () => { + // User is already logged in from beforeAll + await page.goto("/signup"); + + // Should be redirected to /demo-app + await page.waitForURL("**/demo-app", { timeout: 5000 }); + expect(page.url()).toContain("/demo-app"); + }); +});