Skip to content

Commit

Permalink
feat: handle state transition edge cases
Browse files Browse the repository at this point in the history
  • Loading branch information
aeneasr committed Jan 15, 2025
1 parent ef8de07 commit 8deedd6
Show file tree
Hide file tree
Showing 15 changed files with 85 additions and 37 deletions.
25 changes: 11 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/elements-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"dependencies": {
"@ory/client-fetch": "^1.15.12",
"@ory/client-fetch": "~1.16.1",
"@radix-ui/react-dropdown-menu": "2.1.2",
"class-variance-authority": "0.7.0",
"clsx": "2.1.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,20 @@ const wrapper = ({ children }: PropsWithChildren) => (
flow={
{
active: "code",
ui: { nodes: [], action: "", method: "" },
ui: {
nodes: [
{
group: "code",
attributes: {
node_type: "input",
name: "code",
type: "text",
},
},
],
action: "",
method: "",
},
} as unknown as LoginFlow // Fine, we're just testing the resolver
}
flowType={FlowType.Login}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { FlowType, UiNode, UiNodeInputAttributes } from "@ory/client-fetch"
import { useOryFlow } from "@ory/elements-react"
import { useFormContext } from "react-hook-form"
import { useIntl } from "react-intl"
import { initFlowUrl, restartFlowUrl } from "../../utils/url"
import { initFlowUrl } from "../../utils/url"

export function DefaultCardFooter() {
const { flowType } = useOryFlow()
Expand Down
6 changes: 5 additions & 1 deletion packages/elements-react/src/theme/default/flows/error.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,9 @@ export function Error({
error,
children,
}: PropsWithChildren<ErrorFlowContextProps>) {
return <div>{JSON.stringify(error) || children}</div>
return (

Check warning on line 22 in packages/elements-react/src/theme/default/flows/error.tsx

View check run for this annotation

Codecov / codecov/patch

packages/elements-react/src/theme/default/flows/error.tsx#L22

Added line #L22 was not covered by tests
<div data-testid={"ory/ui/error/raw"}>
{JSON.stringify(error) || children}
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ describe("url utils", () => {
const flow = {}

// Not sure how to mock this.
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
;(window.location.href =
"http://example.com?return_to=http://example.com/return"),
expect(initFlowUrl(sdkUrl, flowType, flow)).toBe(
Expand Down
8 changes: 4 additions & 4 deletions packages/elements-react/src/util/i18n/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,16 @@ export const uiTextToFormattedMessage = (
new Date(value),
new Date(),
),
[key + "_since_minutes"]: Math.abs(
[key + "_since_minutes"]: Math.ceil(
(value - new Date().getTime() / 1000) / 60,
).toFixed(2),
).toFixed(0),
[key + "_until"]: intl.formatDateTimeRange(
new Date(),
new Date(value),
),
[key + "_until_minutes"]: Math.abs(
[key + "_until_minutes"]: Math.ceil(
(new Date().getTime() / 1000 - value) / 60,
).toFixed(2),
).toFixed(0),
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions packages/elements-react/src/util/internal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright © 2025 Ory Corp
// SPDX-License-Identifier: Apache-2.0

export function replaceWindowFlowId(flow: string) {
const url = new URL(window.location.href)
url.searchParams.set("flow", flow)
window.location.href = url.toString()

Check warning on line 7 in packages/elements-react/src/util/internal.ts

View check run for this annotation

Codecov / codecov/patch

packages/elements-react/src/util/internal.ts#L4-L7

Added lines #L4 - L7 were not covered by tests
}
9 changes: 7 additions & 2 deletions packages/elements-react/src/util/onSubmitLogin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
import { OnSubmitHandlerProps } from "./submitHandler"
import { OryFlowContainer } from "./flowContainer"
import { frontendClient } from "./client"
import { replaceWindowFlowId } from "./internal"

Check warning on line 14 in packages/elements-react/src/util/onSubmitLogin.ts

View check run for this annotation

Codecov / codecov/patch

packages/elements-react/src/util/onSubmitLogin.ts#L14

Added line #L14 was not covered by tests

/**
* Use this method to submit a login flow. This method is used in the `onSubmit` handler of the login form.
Expand Down Expand Up @@ -49,8 +50,12 @@ export async function onSubmitLogin(
})
.catch(
handleFlowError({
onRestartFlow: () => {
onRedirect(loginUrl(config), true)
onRestartFlow: (useFlowId?: string) => {

Check warning on line 53 in packages/elements-react/src/util/onSubmitLogin.ts

View check run for this annotation

Codecov / codecov/patch

packages/elements-react/src/util/onSubmitLogin.ts#L53

Added line #L53 was not covered by tests
if (useFlowId) {
replaceWindowFlowId(useFlowId)

Check warning on line 55 in packages/elements-react/src/util/onSubmitLogin.ts

View check run for this annotation

Codecov / codecov/patch

packages/elements-react/src/util/onSubmitLogin.ts#L55

Added line #L55 was not covered by tests
} else {
onRedirect(loginUrl(config), true)

Check warning on line 57 in packages/elements-react/src/util/onSubmitLogin.ts

View check run for this annotation

Codecov / codecov/patch

packages/elements-react/src/util/onSubmitLogin.ts#L57

Added line #L57 was not covered by tests
}
},
onValidationError: (body: LoginFlow) => {
setFlowContainer({
Expand Down
11 changes: 8 additions & 3 deletions packages/elements-react/src/util/onSubmitRecovery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ import { frontendClient } from "./client"
import { OryClientConfiguration } from "./clientConfiguration"
import { OryFlowContainer } from "./flowContainer"
import { OnSubmitHandlerProps } from "./submitHandler"
import { replaceWindowFlowId } from "./internal"

Check warning on line 20 in packages/elements-react/src/util/onSubmitRecovery.ts

View check run for this annotation

Codecov / codecov/patch

packages/elements-react/src/util/onSubmitRecovery.ts#L20

Added line #L20 was not covered by tests

/**
* Use this method to submit a recovery flow. This method is used in the `onSubmit` handler of the recovery form.
*
* @param config - The configuration object.
* @param flow - The flow object.
* @param setFlowContainer - This method is used to update the flow container when a validation error occurs, for example.
* @param body- The form values to submit.
* @param body - The form values to submit.
* @param onRedirect - This method is used to redirect the user to a different page.
*/
export async function onSubmitRecovery(
Expand Down Expand Up @@ -66,8 +67,12 @@ export async function onSubmitRecovery(
})
.catch(
handleFlowError({
onRestartFlow: () => {
onRedirect(recoveryUrl(config), true)
onRestartFlow: (useFlowId) => {

Check warning on line 70 in packages/elements-react/src/util/onSubmitRecovery.ts

View check run for this annotation

Codecov / codecov/patch

packages/elements-react/src/util/onSubmitRecovery.ts#L70

Added line #L70 was not covered by tests
if (useFlowId) {
replaceWindowFlowId(useFlowId)

Check warning on line 72 in packages/elements-react/src/util/onSubmitRecovery.ts

View check run for this annotation

Codecov / codecov/patch

packages/elements-react/src/util/onSubmitRecovery.ts#L72

Added line #L72 was not covered by tests
} else {
onRedirect(recoveryUrl(config), true)

Check warning on line 74 in packages/elements-react/src/util/onSubmitRecovery.ts

View check run for this annotation

Codecov / codecov/patch

packages/elements-react/src/util/onSubmitRecovery.ts#L74

Added line #L74 was not covered by tests
}
},
onValidationError: (body: RecoveryFlow | { error: GenericError }) => {
if ("error" in body) {
Expand Down
9 changes: 7 additions & 2 deletions packages/elements-react/src/util/onSubmitRegistration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import { OryFlowContainer } from "./flowContainer"
import { OnSubmitHandlerProps } from "./submitHandler"
import { frontendClient } from "./client"
import { replaceWindowFlowId } from "./internal"

Check warning on line 15 in packages/elements-react/src/util/onSubmitRegistration.ts

View check run for this annotation

Codecov / codecov/patch

packages/elements-react/src/util/onSubmitRegistration.ts#L15

Added line #L15 was not covered by tests

/**
* Use this method to submit a registration flow. This method is used in the `onSubmit` handler of the registration form.
Expand Down Expand Up @@ -60,8 +61,12 @@ export async function onSubmitRegistration(
})
.catch(
handleFlowError({
onRestartFlow: () => {
onRedirect(registrationUrl(config), true)
onRestartFlow: (useFlowId) => {

Check warning on line 64 in packages/elements-react/src/util/onSubmitRegistration.ts

View check run for this annotation

Codecov / codecov/patch

packages/elements-react/src/util/onSubmitRegistration.ts#L64

Added line #L64 was not covered by tests
if (useFlowId) {
replaceWindowFlowId(useFlowId)

Check warning on line 66 in packages/elements-react/src/util/onSubmitRegistration.ts

View check run for this annotation

Codecov / codecov/patch

packages/elements-react/src/util/onSubmitRegistration.ts#L66

Added line #L66 was not covered by tests
} else {
onRedirect(registrationUrl(config), true)

Check warning on line 68 in packages/elements-react/src/util/onSubmitRegistration.ts

View check run for this annotation

Codecov / codecov/patch

packages/elements-react/src/util/onSubmitRegistration.ts#L68

Added line #L68 was not covered by tests
}
},
onValidationError: (body: RegistrationFlow) => {
setFlowContainer({
Expand Down
9 changes: 7 additions & 2 deletions packages/elements-react/src/util/onSubmitSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import { OryFlowContainer } from "./flowContainer"
import { OnSubmitHandlerProps } from "./submitHandler"
import { frontendClient } from "./client"
import { replaceWindowFlowId } from "./internal"

Check warning on line 17 in packages/elements-react/src/util/onSubmitSettings.ts

View check run for this annotation

Codecov / codecov/patch

packages/elements-react/src/util/onSubmitSettings.ts#L17

Added line #L17 was not covered by tests

/**
* Use this method to submit a settings flow. This method is used in the `onSubmit` handler of the settings form.
Expand Down Expand Up @@ -64,8 +65,12 @@ export async function onSubmitSettings(
})
.catch(
handleFlowError({
onRestartFlow: () => {
onRedirect(settingsUrl(config), true)
onRestartFlow: (useFlowId) => {

Check warning on line 68 in packages/elements-react/src/util/onSubmitSettings.ts

View check run for this annotation

Codecov / codecov/patch

packages/elements-react/src/util/onSubmitSettings.ts#L68

Added line #L68 was not covered by tests
if (useFlowId) {
replaceWindowFlowId(useFlowId)

Check warning on line 70 in packages/elements-react/src/util/onSubmitSettings.ts

View check run for this annotation

Codecov / codecov/patch

packages/elements-react/src/util/onSubmitSettings.ts#L70

Added line #L70 was not covered by tests
} else {
onRedirect(settingsUrl(config), true)

Check warning on line 72 in packages/elements-react/src/util/onSubmitSettings.ts

View check run for this annotation

Codecov / codecov/patch

packages/elements-react/src/util/onSubmitSettings.ts#L72

Added line #L72 was not covered by tests
}
},
onValidationError: (body: SettingsFlow) => {
setFlowContainer({
Expand Down
9 changes: 7 additions & 2 deletions packages/elements-react/src/util/onSubmitVerification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
import { OryFlowContainer } from "./flowContainer"
import { OnSubmitHandlerProps } from "./submitHandler"
import { frontendClient } from "./client"
import { replaceWindowFlowId } from "./internal"

Check warning on line 14 in packages/elements-react/src/util/onSubmitVerification.ts

View check run for this annotation

Codecov / codecov/patch

packages/elements-react/src/util/onSubmitVerification.ts#L14

Added line #L14 was not covered by tests

/**
* Use this method to submit a verification flow. This method is used in the `onSubmit` handler of the verification form.
Expand Down Expand Up @@ -49,8 +50,12 @@ export async function onSubmitVerification(
)
.catch(
handleFlowError({
onRestartFlow: () => {
onRedirect(verificationUrl(config), true)
onRestartFlow: (useFlowId) => {

Check warning on line 53 in packages/elements-react/src/util/onSubmitVerification.ts

View check run for this annotation

Codecov / codecov/patch

packages/elements-react/src/util/onSubmitVerification.ts#L53

Added line #L53 was not covered by tests
if (useFlowId) {
replaceWindowFlowId(useFlowId)

Check warning on line 55 in packages/elements-react/src/util/onSubmitVerification.ts

View check run for this annotation

Codecov / codecov/patch

packages/elements-react/src/util/onSubmitVerification.ts#L55

Added line #L55 was not covered by tests
} else {
onRedirect(verificationUrl(config), true)

Check warning on line 57 in packages/elements-react/src/util/onSubmitVerification.ts

View check run for this annotation

Codecov / codecov/patch

packages/elements-react/src/util/onSubmitVerification.ts#L57

Added line #L57 was not covered by tests
}
},
onValidationError: (body: VerificationFlow) => {
setFlowContainer({
Expand Down
6 changes: 3 additions & 3 deletions packages/elements-react/src/util/ui/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ type Entries<T> = {
*
* This method the default, identifier_first, and profile groups.
*
* @param nodes The nodes to extract the auth methods from
* @param excludeAuthMethods A list of auth methods to exclude
* @param nodes - The nodes to extract the auth methods from
* @param excludeAuthMethods - A list of auth methods to exclude
*/
export function nodesToAuthMethodGroups(
nodes: Array<UiNode>,
Expand Down Expand Up @@ -145,7 +145,7 @@ export function nodesToAuthMethodGroups(
/**
* Groups nodes by their group and returns an object with the groups and entries.
*
* @param nodes
* @param nodes - The nodes to group
*/
export function useNodesGroups(nodes: UiNode[]) {
const groupSorter = useGroupSorter()
Expand Down
2 changes: 1 addition & 1 deletion packages/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"types": "./dist/index.d.ts",
"private": false,
"dependencies": {
"@ory/client-fetch": "^1.15.6",
"@ory/client-fetch": "~1.16.0",
"cookie": "^1.0.1",
"psl": "^1.15.0",
"set-cookie-parser": "^2.7.1"
Expand Down

0 comments on commit 8deedd6

Please sign in to comment.