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 1f21254
Show file tree
Hide file tree
Showing 14 changed files with 71 additions and 36 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 @@ -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 (
<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()
}
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"

/**
* 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) => {
if (useFlowId) {
replaceWindowFlowId(useFlowId)
} else {
onRedirect(loginUrl(config), true)
}
},
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"

/**
* 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) => {
if (useFlowId) {
replaceWindowFlowId(useFlowId)
} else {
onRedirect(recoveryUrl(config), true)
}
},
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"

/**
* 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) => {
if (useFlowId) {
replaceWindowFlowId(useFlowId)
} else {
onRedirect(registrationUrl(config), true)
}
},
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"

/**
* 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) => {
if (useFlowId) {
replaceWindowFlowId(useFlowId)
} else {
onRedirect(settingsUrl(config), true)
}
},
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"

/**
* 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) => {
if (useFlowId) {
replaceWindowFlowId(useFlowId)
} else {
onRedirect(verificationUrl(config), true)
}
},
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 1f21254

Please sign in to comment.