From 3eb3abeea63ba2b8ff5788344633a34321366f5e Mon Sep 17 00:00:00 2001 From: Daniel Francesconi Date: Wed, 13 Sep 2023 15:03:11 +0200 Subject: [PATCH] fix: `additionalProps` should be conditional on the `UserAuthCard` (#138) * fix: hide signup url when `undefined` * fix: include flow id in uri query params * chore: make `additionalProps` optional and add tests --------- Co-authored-by: Alano Terblanche <18033717+Benehiko@users.noreply.github.com> --- examples/react-spa/src/Login.tsx | 2 +- .../ory/user-auth-card.spec.tsx | 78 +++++++++++++++++ src/react-components/ory/user-auth-card.tsx | 87 ++++++++++--------- src/stories/Ory/Auth.stories.tsx | 27 +++++- 4 files changed, 151 insertions(+), 43 deletions(-) diff --git a/examples/react-spa/src/Login.tsx b/examples/react-spa/src/Login.tsx index 11f2fd909..c1be6e474 100644 --- a/examples/react-spa/src/Login.tsx +++ b/examples/react-spa/src/Login.tsx @@ -35,7 +35,7 @@ export const Login = (): JSX.Element => { // flow contains the form fields and csrf token .then(({ data: flow }) => { // Update URI query params to include flow id - setSearchParams({}) + setSearchParams({ ["flow"]: flow.id }) // Set the flow data setFlow(flow) }) diff --git a/src/react-components/ory/user-auth-card.spec.tsx b/src/react-components/ory/user-auth-card.spec.tsx index 52e0a7ea9..6ce6fc5be 100644 --- a/src/react-components/ory/user-auth-card.spec.tsx +++ b/src/react-components/ory/user-auth-card.spec.tsx @@ -142,6 +142,10 @@ test("ory auth card verification flow", async ({ mount }) => { await expect(component).toContainText("Verification") await expect(component.locator('a[href="/signup"]')).toBeVisible() + + await expect(component).toContainText("Don't have an account?", { + ignoreCase: true, + }) }) test("ory auth card recovery flow", async ({ mount }) => { @@ -239,3 +243,77 @@ test("ory auth card login with code", async ({ mount }) => { "Sign in with code", ) }) + +test("ory auth card login should work without additionalProps", async ({ + mount, +}) => { + const component = await mount( + , + ) + + const loginComponent = new AuthPage(loginCodeFixture.ui.nodes, component) + await loginComponent.expectTraitFields() + + await expect(component).toContainText("Sign in", { ignoreCase: true }) + await expect(component).not.toContainText("Don't have an account?", { + ignoreCase: true, + }) +}) + +test("ory auth card registration should work without additionalProps", async ({ + mount, +}) => { + const component = await mount( + , + ) + + const registrationComponent = new AuthPage( + registrationCodeFixture.ui.nodes, + component, + ) + await registrationComponent.expectTraitFields() + + await expect(component).toContainText("Sign up", { ignoreCase: true }) + await expect(component).not.toContainText("Already have an account?", { + ignoreCase: true, + }) +}) + +test("ory auth card recovery should work without additionalProps", async ({ + mount, +}) => { + const component = await mount( + , + ) + + const recoveryComponent = new AuthPage(recoveryFixture.ui.nodes, component) + await recoveryComponent.expectTraitFields() + + await expect(component).toContainText("Recover your account", { + ignoreCase: true, + }) + await expect(component).not.toContainText("Already have an account?", { + ignoreCase: true, + }) +}) + +test("ory auth card verification should work without additionalProps", async ({ + mount, +}) => { + const component = await mount( + , + ) + + const verificationComponent = new AuthPage( + verificationFixture.ui.nodes, + component, + ) + await verificationComponent.expectTraitFields() + + await expect(component).toContainText("Verify your account", { + ignoreCase: true, + }) + await expect(component).not.toContainText("Don't have an account?", { + ignoreCase: true, + }) +}) diff --git a/src/react-components/ory/user-auth-card.tsx b/src/react-components/ory/user-auth-card.tsx index 5cc475d01..dbba2c8ed 100644 --- a/src/react-components/ory/user-auth-card.tsx +++ b/src/react-components/ory/user-auth-card.tsx @@ -17,7 +17,6 @@ import { MessageSection, MessageSectionProps } from "./helpers/common" import { NodeMessages } from "./helpers/error-messages" import { FilterFlowNodes } from "./helpers/filter-flow-nodes" import { useScriptNodes } from "./helpers/node-script" -import { SelfServiceFlow } from "./helpers/types" import { UserAuthForm, UserAuthFormAdditionalProps, @@ -76,22 +75,22 @@ export type UserAuthCardProps = { | { flow: LoginFlow flowType: "login" - additionalProps: LoginSectionAdditionalProps + additionalProps?: LoginSectionAdditionalProps } | { flow: RegistrationFlow flowType: "registration" - additionalProps: RegistrationSectionAdditionalProps + additionalProps?: RegistrationSectionAdditionalProps } | { flow: RecoveryFlow flowType: "recovery" - additionalProps: RecoverySectionAdditionalProps + additionalProps?: RecoverySectionAdditionalProps } | { flow: VerificationFlow flowType: "verification" - additionalProps: VerificationSectionAdditionalProps + additionalProps?: VerificationSectionAdditionalProps } ) @@ -315,7 +314,7 @@ export const UserAuthCard = ({ ...additionalProps, }) - if (isLoggedIn(flow)) { + if (isLoggedIn(flow) && additionalProps?.logoutURL) { message = { text: intl.formatMessage({ id: "login.logout-label", @@ -325,10 +324,10 @@ export const UserAuthCard = ({ id: "login.logout-button", defaultMessage: "Logout", }), - url: additionalProps.logoutURL, dataTestId: "logout-link", + url: additionalProps.logoutURL, } - } else if (additionalProps.signupURL) { + } else if (additionalProps?.signupURL) { message = { text: intl.formatMessage({ id: "login.registration-label", @@ -350,17 +349,19 @@ export const UserAuthCard = ({ $flow = RegistrationSection({ nodes: flow.ui.nodes, }) - message = { - text: intl.formatMessage({ - id: "registration.login-label", - defaultMessage: "Already have an account?", - }), - url: additionalProps.loginURL, - buttonText: intl.formatMessage({ - id: "registration.login-button", - defaultMessage: "Sign in", - }), - dataTestId: "cta-link", + if (additionalProps?.loginURL) { + message = { + text: intl.formatMessage({ + id: "registration.login-label", + defaultMessage: "Already have an account?", + }), + url: additionalProps.loginURL, + buttonText: intl.formatMessage({ + id: "registration.login-button", + defaultMessage: "Sign in", + }), + dataTestId: "cta-link", + } } break // both verification and recovery use the same flow. @@ -368,34 +369,38 @@ export const UserAuthCard = ({ $flow = LinkSection({ nodes: flow.ui.nodes, }) - message = { - text: intl.formatMessage({ - id: "recovery.login-label", - defaultMessage: "Remember your credentials?", - }), - buttonText: intl.formatMessage({ - id: "recovery.login-button", - defaultMessage: "Sign in", - }), - url: additionalProps.loginURL, - dataTestId: "cta-link", + if (additionalProps?.loginURL) { + message = { + text: intl.formatMessage({ + id: "recovery.login-label", + defaultMessage: "Remember your credentials?", + }), + buttonText: intl.formatMessage({ + id: "recovery.login-button", + defaultMessage: "Sign in", + }), + url: additionalProps.loginURL, + dataTestId: "cta-link", + } } break case "verification": $flow = LinkSection({ nodes: flow.ui.nodes, }) - message = { - text: intl.formatMessage({ - id: "verification.registration-label", - defaultMessage: "Don't have an account?", - }), - buttonText: intl.formatMessage({ - id: "verification.registration-button", - defaultMessage: "Sign up", - }), - url: additionalProps.signupURL, - dataTestId: "cta-link", + if (additionalProps?.signupURL) { + message = { + text: intl.formatMessage({ + id: "verification.registration-label", + defaultMessage: "Don't have an account?", + }), + buttonText: intl.formatMessage({ + id: "verification.registration-button", + defaultMessage: "Sign up", + }), + url: additionalProps.signupURL, + dataTestId: "cta-link", + } } break default: diff --git a/src/stories/Ory/Auth.stories.tsx b/src/stories/Ory/Auth.stories.tsx index d565b5579..0e1185028 100644 --- a/src/stories/Ory/Auth.stories.tsx +++ b/src/stories/Ory/Auth.stories.tsx @@ -154,6 +154,13 @@ LoginAuthCardWithCodeSubmit.args = { }, } +export const LoginAuthCardWithoutAdditionalProps = Template.bind({}) + +LoginAuthCardWithoutAdditionalProps.args = { + flow: loginFlow as LoginFlow, + flowType: "login", +} + export const RegistrationAuthCard = Template.bind({}) RegistrationAuthCard.args = { @@ -168,7 +175,6 @@ RegistrationAuthCard.args = { export const RegistrationAuthCardWebAuthn = Template.bind({}) RegistrationAuthCardWebAuthn.args = { - title: "Create an account for Acme", flow: registrationFlowWebAuthn as RegistrationFlow, flowType: "registration", includeScripts: true, @@ -177,6 +183,12 @@ RegistrationAuthCardWebAuthn.args = { }, } +export const RegistrationAuthCardWithoutAdditionalProps = Template.bind({}) +RegistrationAuthCardWithoutAdditionalProps.args = { + flow: registrationFlow as RegistrationFlow, + flowType: "registration", +} + export const RecoveryAuthCard = Template.bind({}) RecoveryAuthCard.args = { @@ -188,6 +200,12 @@ RecoveryAuthCard.args = { }, } +export const RecoveryAuthCardWithoutAdditionalProps = Template.bind({}) +RecoveryAuthCardWithoutAdditionalProps.args = { + flow: recoveryFlow as RecoveryFlow, + flowType: "recovery", +} + export const VerificationAuthCard = Template.bind({}) VerificationAuthCard.args = { @@ -207,3 +225,10 @@ VerificationSubmittedAuthCard.args = { signupURL: "https://acme.com/login", }, } + +export const VerificationAuthCardWithoutAdditionalProps = Template.bind({}) + +VerificationAuthCardWithoutAdditionalProps.args = { + flow: verificationFlow as VerificationFlow, + flowType: "verification", +}