diff --git a/site/components/SignIn/SignInForm.test.tsx b/site/components/SignIn/SignInForm.test.tsx index 0f1797de4b606..1306fd43fa0e0 100644 --- a/site/components/SignIn/SignInForm.test.tsx +++ b/site/components/SignIn/SignInForm.test.tsx @@ -55,7 +55,29 @@ describe("SignInForm", () => { act(() => elem.click()) // Then - // Should redirect because login was successfully + // Should redirect because login was successful await waitFor(() => expect(singletonRouter).toMatchObject({ asPath: "/" })) }) + + it("respects ?redirect query parameter when complete", async () => { + // Given + const loginHandler = (_email: string, _password: string) => Promise.resolve() + // Set a path to redirect to after login is successful + mockRouter.setCurrentUrl("/login?redirect=%2Fsome%2Fother%2Fpath") + + // When + // Render the component + const { container } = render() + // Set user / password + const inputs = container.querySelectorAll("input") + fireEvent.change(inputs[0], { target: { value: "test@coder.com" } }) + fireEvent.change(inputs[1], { target: { value: "password" } }) + // Click sign-in + const elem = await screen.findByText("Sign In") + act(() => elem.click()) + + // Then + // Should redirect to /some/other/path because ?redirect was specified and login was successful + await waitFor(() => expect(singletonRouter).toMatchObject({ asPath: "/some/other/path" })) + }) }) diff --git a/site/components/SignIn/SignInForm.tsx b/site/components/SignIn/SignInForm.tsx index a456cf57ed56e..fdb0e0c43ae3f 100644 --- a/site/components/SignIn/SignInForm.tsx +++ b/site/components/SignIn/SignInForm.tsx @@ -1,6 +1,6 @@ import { makeStyles } from "@material-ui/core/styles" import { FormikContextType, useFormik } from "formik" -import { useRouter } from "next/router" +import { NextRouter, useRouter } from "next/router" import React from "react" import { useSWRConfig } from "swr" import * as Yup from "yup" @@ -9,6 +9,7 @@ import { Welcome } from "./Welcome" import { FormTextField } from "../Form" import * as API from "./../../api" import { LoadingButton } from "./../Button" +import { firstOrItem } from "../../util/array" /** * BuiltInAuthFormValues describes a form using built-in (email/password) @@ -61,7 +62,9 @@ export const SignInForm: React.FC = ({ await loginHandler(email, password) // Tell SWR to invalidate the cache for the user endpoint await mutate("/api/v2/users/me") - await router.push("/") + + const redirect = getRedirectFromRouter(router) + await router.push(redirect) } catch (err) { helpers.setFieldError("password", "The username or password is incorrect.") } @@ -117,3 +120,12 @@ export const SignInForm: React.FC = ({ ) } + +const getRedirectFromRouter = (router: NextRouter) => { + const defaultRedirect = "/" + if (router.query?.redirect) { + return firstOrItem(router.query.redirect, defaultRedirect) + } else { + return defaultRedirect + } +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy