diff --git a/package-lock.json b/package-lock.json index 28c17717f..9eff75d7a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,6 +29,7 @@ "@storybook/node-logger": "6.5.16", "@storybook/react": "6.5.16", "@types/express": "^4.17.15", + "@types/flat": "5.0.2", "@types/node": "18.14.0", "@types/react": "18.0.27", "@types/react-dom": "18.0.10", @@ -47,6 +48,7 @@ "eslint-plugin-react-hooks": "4.6.0", "eslint-plugin-storybook": "0.6.11", "eslint-plugin-tsdoc": "0.2.17", + "flat": "5.0.2", "lerna": "5.6.2", "license-checker": "^25.0.1", "nx": "15.7.2", @@ -9869,6 +9871,12 @@ "@types/range-parser": "*" } }, + "node_modules/@types/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-3zsplnP2djeps5P9OyarTxwRpMLoe5Ash8aL9iprw0JxB+FAHjY+ifn4yZUuW4/9hqtnmor6uvjSRzJhiVbrEQ==", + "dev": true + }, "node_modules/@types/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", @@ -39881,6 +39889,12 @@ "@types/range-parser": "*" } }, + "@types/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-3zsplnP2djeps5P9OyarTxwRpMLoe5Ash8aL9iprw0JxB+FAHjY+ifn4yZUuW4/9hqtnmor6uvjSRzJhiVbrEQ==", + "dev": true + }, "@types/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", diff --git a/package.json b/package.json index df51b64aa..598c387e3 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,8 @@ }, "homepage": "https://github.com/ory/elements#readme", "devDependencies": { + "@types/flat": "5.0.2", + "flat": "5.0.2", "@babel/core": "^7.18.10", "@ory/client": "1.1.22", "@ory/integrations": "1.1.0", diff --git a/src/react-components/ory/helpers/user-auth-form.spec.tsx b/src/react-components/ory/helpers/user-auth-form.spec.tsx new file mode 100644 index 000000000..2bf4a58e0 --- /dev/null +++ b/src/react-components/ory/helpers/user-auth-form.spec.tsx @@ -0,0 +1,61 @@ +import { expect, test } from "@playwright/experimental-ct-react" +import { + AuthPage, + RandomString, + registrationFixture, + Traits, +} from "../../../test" +import { UpdateBody, UserAuthForm } from "./user-auth-form" +import { RegistrationSection } from "../sections/registration-section" + +test("user auth form test", async ({ mount }) => { + let body: UpdateBody | undefined + const traits: Record = { + "traits.firstName": { + group: "password", + label: "First Name", + value: RandomString(), + type: "input", + }, + "traits.email": { + group: "password", + label: "Email", + value: RandomString() + "@example.com", + type: "input", + }, + password: { + group: "password", + label: "Password", + value: RandomString(), + type: "input", + }, + csrf_token: { + group: "default", + label: "", + value: RandomString(), + type: "hidden", + }, + } + const component = await mount( + { + body = b + }} + > + + , + ) + + const registrationComponent = new AuthPage(traits, component) + + await registrationComponent.submitForm() + + expect(body).toBeTruthy() + expect(body).toHaveProperty("method", "password") + expect(body).toHaveProperty("password", traits.password.value) + expect(body).toHaveProperty("traits", { + email: traits["traits.email"].value, + firstName: traits["traits.firstName"].value, + }) +}) diff --git a/src/react-components/ory/helpers/user-auth-form.tsx b/src/react-components/ory/helpers/user-auth-form.tsx index 0afccac0e..bcf19dcf5 100644 --- a/src/react-components/ory/helpers/user-auth-form.tsx +++ b/src/react-components/ory/helpers/user-auth-form.tsx @@ -7,22 +7,25 @@ import { } from "@ory/client" import { FilterNodesByGroups } from "@ory/integrations/ui" import cn from "classnames" +import { unflatten } from "flat" import { formStyle } from "../../../theme" import { FilterFlowNodes } from "./filter-flow-nodes" import { SelfServiceFlow } from "./types" +export type UpdateBody = + | UpdateLoginFlowBody + | UpdateRegistrationFlowBody + | UpdateRecoveryFlowBody + | UpdateVerificationFlowBody + | UpdateSettingsFlowBody + export type UserAuthFormAdditionalProps = { onSubmit?: ({ body, event, }: { - body: - | UpdateLoginFlowBody - | UpdateRegistrationFlowBody - | UpdateRecoveryFlowBody - | UpdateVerificationFlowBody - | UpdateSettingsFlowBody + body: UpdateBody event?: React.FormEvent }) => void } @@ -65,12 +68,7 @@ export const UserAuthForm = ({ const formData = new FormData(form) // map the entire form data to JSON for the request body - let body = Object.fromEntries(formData) as unknown as - | UpdateLoginFlowBody - | UpdateRegistrationFlowBody - | UpdateRecoveryFlowBody - | UpdateVerificationFlowBody - | UpdateSettingsFlowBody + let body = Object.fromEntries(formData) as unknown as UpdateBody // We need the method specified from the name and value of the submit button. // when multiple submit buttons are present, the clicked one's value is used. @@ -84,7 +82,7 @@ export const UserAuthForm = ({ } } - onSubmit({ body, event }) + onSubmit({ body: unflatten(body) as UpdateBody, event }) }, })} {...props}