UNPKG

@ory/elements-react

Version:

Ory Elements React - a collection of React components for authentication UIs.

1 lines 3.43 MB
{"version":3,"sources":["../../../src/theme/default/components/card/index.tsx","../../../src/theme/default/assets/ory-badge-horizontal.svg","../../../src/theme/default/assets/ory-badge-vertical.svg","../../../src/theme/default/components/card/badge.tsx","../../../src/theme/default/components/card/content.tsx","../../../src/theme/default/components/card/footer.tsx","../../../src/util/i18n/index.ts","../../../src/util/i18n/generated/kratosMessages.ts","../../../src/util/nodes.ts","../../../src/util/ui/index.ts","../../../src/context/component.tsx","../../../src/context/defaultNodeSorter.ts","../../../src/util/utilFixSDKTypesHelper.ts","../../../src/theme/default/utils/logout.ts","../../../src/util/client.ts","../../../src/theme/default/utils/url.ts","../../../src/theme/default/components/card/header.tsx","../../../src/theme/default/utils/constructCardHeader.ts","../../../src/theme/default/components/card/current-identifier-button.tsx","../../../src/theme/default/utils/attributes.ts","../../../src/util/omitAttributes.ts","../../../src/theme/default/assets/icons/arrow-left.svg","../../../src/theme/default/components/card/logo.tsx","../../../src/theme/default/utils/cn.ts","../../../src/theme/default/components/form/index.tsx","../../../src/theme/default/components/form/sso.tsx","../../../src/theme/default/provider-logos/apple.svg","../../../src/theme/default/provider-logos/auth0.svg","../../../src/theme/default/provider-logos/discord.svg","../../../src/theme/default/provider-logos/facebook.svg","../../../src/theme/default/provider-logos/github.svg","../../../src/theme/default/provider-logos/gitlab.svg","../../../src/theme/default/provider-logos/google.svg","../../../src/theme/default/provider-logos/linkedin.svg","../../../src/theme/default/provider-logos/microsoft.svg","../../../src/theme/default/provider-logos/slack.svg","../../../src/theme/default/provider-logos/spotify.svg","../../../src/theme/default/provider-logos/yandex.svg","../../../src/theme/default/provider-logos/x.svg","../../../src/theme/default/provider-logos/index.ts","../../../src/theme/default/components/form/spinner.tsx","../../../src/theme/default/components/form/button.tsx","../../../src/theme/default/components/card/auth-method-list-item.tsx","../../../src/theme/default/assets/icons/alert-triangle.svg","../../../src/theme/default/assets/icons/code-asterix.svg","../../../src/theme/default/assets/icons/code.svg","../../../src/theme/default/assets/icons/passkey.svg","../../../src/theme/default/assets/icons/password.svg","../../../src/theme/default/assets/icons/totp.svg","../../../src/theme/default/assets/icons/webauthn.svg","../../../src/theme/default/utils/form.ts","../../../src/theme/default/components/card/list-item.tsx","../../../src/theme/default/components/form/checkbox.tsx","../../../src/theme/default/components/ui/checkbox-label.tsx","../../../src/theme/default/components/form/group-container.tsx","../../../src/util/childCounter.ts","../../../src/theme/default/components/form/horizontal-divider.tsx","../../../src/theme/default/components/form/image.tsx","../../../src/theme/default/components/form/input.tsx","../../../src/theme/default/assets/icons/eye-off.svg","../../../src/theme/default/assets/icons/eye.svg","../../../src/theme/default/components/form/label.tsx","../../../src/theme/default/components/form/select.tsx","../../../src/theme/default/components/form/link-button.tsx","../../../src/theme/default/components/form/pin-code-input.tsx","../../../src/theme/default/components/form/shadcn/otp-input.tsx","../../../src/theme/default/components/form/section.tsx","../../../src/theme/default/components/form/text.tsx","../../../src/theme/default/components/generic/page-header.tsx","../../../src/theme/default/components/ui/user-menu.tsx","../../../src/theme/default/assets/icons/logout.svg","../../../src/theme/default/assets/icons/settings.svg","../../../src/theme/default/utils/user.ts","../../../src/theme/default/components/ui/dropdown-menu.tsx","../../../src/theme/default/components/ui/user-avater.tsx","../../../src/theme/default/assets/icons/user.svg","../../../src/theme/default/components/settings/settings-oidc.tsx","../../../src/theme/default/assets/icons/trash.svg","../../../src/theme/default/components/settings/settings-passkey.tsx","../../../src/theme/default/assets/icons/download.svg","../../../src/theme/default/assets/icons/refresh.svg","../../../src/theme/default/components/settings/settings-recovery-codes.tsx","../../../src/theme/default/components/settings/settings-totp.tsx","../../../src/theme/default/assets/icons/qrcode.svg","../../../src/theme/default/components/settings/settings-webauthn.tsx","../../../src/theme/default/assets/icons/key.svg","../../../src/theme/default/components/card/auth-method-list-container.tsx","../../../src/theme/default/components/form/captcha.tsx","../../../src/theme/default/components/form/consent-scope-checkbox.tsx","../../../src/theme/default/assets/icons/message.svg","../../../src/theme/default/assets/icons/personal.svg","../../../src/theme/default/assets/icons/phone.svg","../../../src/theme/default/components/generic/toast.tsx","../../../src/theme/default/assets/icons/x.svg","../../../src/theme/default/components/default-components.tsx","../../../src/theme/default/flows/error.tsx","../../../src/context/intl-context.tsx","../../../src/context/flow-context.tsx","../../../src/context/form-state.ts","../../../src/components/card/two-step/utils.ts","../../../src/context/config.tsx","../../../src/context/provider.tsx","../../../src/components/card/header.tsx","../../../src/components/form/form-provider.tsx","../../../src/components/form/form-helpers.ts","../../../src/components/form/form-resolver.ts","../../../src/components/card/card.tsx","../../../src/components/card/footer.tsx","../../../src/components/card/content.tsx","../../../src/components/card/card-two-step.tsx","../../../src/components/card/two-step/state-method-active.tsx","../../../src/components/form/form.tsx","../../../src/components/form/useOryFormSubmit.ts","../../../src/util/onSubmitLogin.ts","../../../src/util/sdk-helpers/error.ts","../../../src/util/sdk-helpers/utils.ts","../../../src/util/onSubmitRecovery.ts","../../../src/util/onSubmitRegistration.ts","../../../src/util/onSubmitSettings.ts","../../../src/util/onSubmitVerification.ts","../../../src/components/form/messages.tsx","../../../src/components/form/nodes/node.tsx","../../../src/components/form/nodes/input.tsx","../../../src/components/form/nodes/node-button.tsx","../../../src/components/form/nodes/renderer/button-renderer.tsx","../../../src/components/form/nodes/renderer/checkbox-renderer.tsx","../../../src/components/form/nodes/renderer/consent-checkbox-renderer.tsx","../../../src/components/form/nodes/renderer/image-renderer.tsx","../../../src/components/form/nodes/renderer/input-renderer.tsx","../../../src/components/form/nodes/hooks/useInputProps.tsx","../../../src/components/form/nodes/renderer/select-renderer.tsx","../../../src/components/form/nodes/renderer/sso-button-renderer.tsx","../../../src/components/form/nodes/renderer/text-renderer.tsx","../../../src/components/form/nodes/renderer/index.ts","../../../src/components/form/nodes/renderer/hidden-input-renderer.tsx","../../../src/components/card/two-step/state-provide-identifier.tsx","../../../src/components/form/social.tsx","../../../src/components/card/two-step/state-select-method.tsx","../../../src/components/card/two-step/list-methods.tsx","../../../src/components/form/settings-section.tsx","../../../src/components/form/useResendCode.ts","../../../src/components/card/card-consent.tsx","../../../src/components/generic/divider.tsx","../../../src/components/generic/page-header.tsx","../../../src/components/settings/settings-card.tsx","../../../src/util/i18n/settingsCardMessages.ts","../../../src/util/showToast.tsx","../../../src/components/settings/oidc-settings.tsx","../../../src/components/settings/passkey-settings.tsx","../../../src/components/settings/recovery-codes-settings.tsx","../../../src/components/settings/totp-settings.tsx","../../../src/components/settings/webauthn-settings.tsx","../../../src/locales/af.json","../../../src/locales/ak.json","../../../src/locales/am.json","../../../src/locales/ar.json","../../../src/locales/as.json","../../../src/locales/az.json","../../../src/locales/be.json","../../../src/locales/bg.json","../../../src/locales/bm.json","../../../src/locales/bn.json","../../../src/locales/ca.json","../../../src/locales/cs.json","../../../src/locales/da.json","../../../src/locales/de.json","../../../src/locales/el.json","../../../src/locales/en.json","../../../src/locales/es.json","../../../src/locales/et.json","../../../src/locales/fa.json","../../../src/locales/fi.json","../../../src/locales/fr.json","../../../src/locales/gu.json","../../../src/locales/ha.json","../../../src/locales/he.json","../../../src/locales/hi.json","../../../src/locales/hr.json","../../../src/locales/hu.json","../../../src/locales/hy.json","../../../src/locales/id.json","../../../src/locales/ig.json","../../../src/locales/it.json","../../../src/locales/ja.json","../../../src/locales/ka.json","../../../src/locales/kk.json","../../../src/locales/km.json","../../../src/locales/kn.json","../../../src/locales/ko.json","../../../src/locales/ku.json","../../../src/locales/ky.json","../../../src/locales/lt.json","../../../src/locales/lv.json","../../../src/locales/mk.json","../../../src/locales/ml.json","../../../src/locales/mn.json","../../../src/locales/mr.json","../../../src/locales/ms.json","../../../src/locales/my.json","../../../src/locales/ne.json","../../../src/locales/nl.json","../../../src/locales/no.json","../../../src/locales/or.json","../../../src/locales/pa.json","../../../src/locales/pl.json","../../../src/locales/ps.json","../../../src/locales/pt.json","../../../src/locales/ro.json","../../../src/locales/ru.json","../../../src/locales/sd.json","../../../src/locales/si.json","../../../src/locales/sk.json","../../../src/locales/sl.json","../../../src/locales/so.json","../../../src/locales/sq.json","../../../src/locales/sr.json","../../../src/locales/su.json","../../../src/locales/sv.json","../../../src/locales/sw.json","../../../src/locales/ta.json","../../../src/locales/te.json","../../../src/locales/tg.json","../../../src/locales/th.json","../../../src/locales/tk.json","../../../src/locales/tl.json","../../../src/locales/tr.json","../../../src/locales/ug.json","../../../src/locales/uk.json","../../../src/locales/ur.json","../../../src/locales/uz.json","../../../src/locales/vi.json","../../../src/locales/xh.json","../../../src/locales/yo.json","../../../src/locales/zh.json","../../../src/locales/zu.json","../../../src/locales/index.ts","../../../src/theme/default/flows/login.tsx","../../../src/theme/default/flows/recovery.tsx","../../../src/theme/default/flows/registration.tsx","../../../src/theme/default/flows/settings.tsx","../../../src/theme/default/flows/verification.tsx","../../../src/theme/default/flows/consent.tsx","../../../src/theme/default/utils/oauth2.ts"],"sourcesContent":["// Copyright © 2024 Ory Corp\n// SPDX-License-Identifier: Apache-2.0\n\nimport { OryCardProps, useOryConfiguration } from \"@ory/elements-react\"\nimport { Badge } from \"./badge\"\nimport { DefaultCardContent } from \"./content\"\nimport { DefaultCardFooter } from \"./footer\"\nimport { DefaultCardHeader } from \"./header\"\nimport { DefaultCardLogo } from \"./logo\"\nimport { DefaultCurrentIdentifierButton } from \"./current-identifier-button\"\nimport { ComponentPropsWithoutRef } from \"react\"\nimport { cn } from \"../../utils/cn\"\n\n/**\n * The DefaultCard component is a styled container that serves as the main card layout for Ory Elements.\n *\n * @param props - The properties for the DefaultCard component.\n * @returns\n * @group Components\n * @category Default Components\n */\nexport function DefaultCard({\n children,\n className,\n ...rest\n}: OryCardProps & ComponentPropsWithoutRef<\"div\">) {\n const { project } = useOryConfiguration()\n\n return (\n <div className={cn(\"ory-elements\", className)} {...rest}>\n <div className=\"flex w-full flex-1 items-start justify-center font-sans-default sm:w-[480px] sm:max-w-[480px] sm:items-center\">\n <div\n className=\"relative grid w-full grid-cols-1 gap-8 border-b border-form-border-default bg-form-background-default px-8 py-12 sm:rounded-cards sm:border sm:px-12 sm:py-14\"\n data-testid=\"ory/card\"\n >\n {children}\n {!project.hide_ory_branding && <Badge />}\n </div>\n </div>\n </div>\n )\n}\n\nexport {\n DefaultCardContent,\n DefaultCardFooter,\n DefaultCardHeader,\n DefaultCardLogo,\n DefaultCurrentIdentifierButton,\n}\n","import * as React from \"react\";\nconst SvgOryBadgeHorizontal = props => <svg xmlns=\"http://www.w3.org/2000/svg\" width={props?.width ? props.width : props?.size ?? 20} height={props?.height ? props.height : props?.size ?? 20} fill=\"none\" {...props}><path fill=\"currentColor\" d=\"M18.007 8h-1.71l2.007-3.996L16.296 0h1.711l1.145 2.301L20.327 0H22z\" /><path fill=\"currentColor\" fillRule=\"evenodd\" d=\"M12.902 4.86a2.47 2.47 0 0 0 1.796-2.365v-.038C14.687 1.097 13.592 0 12.245 0H9.037v1.44l1.208 1.985H9.04V8h1.51V4.949h.633L13.04 8h1.775zm-.876-1.431h.223c.52 0 .943-.427.943-.953a.95.95 0 0 0-.943-.952h-1.39zM4 0a4 4 0 1 0-.001 7.999A4 4 0 0 0 4 0M1.524 4a2.476 2.476 0 1 0 4.952 0 2.476 2.476 0 0 0-4.952 0\" clipRule=\"evenodd\" /></svg>;\nexport default SvgOryBadgeHorizontal;","import * as React from \"react\";\nconst SvgOryBadgeVertical = props => <svg xmlns=\"http://www.w3.org/2000/svg\" width={props?.width ? props.width : props?.size ?? 20} height={props?.height ? props.height : props?.size ?? 20} fill=\"none\" {...props}><path fill=\"currentColor\" d=\"M8 3.993v1.71L4.004 3.697 0 5.704V3.993l2.301-1.145L0 1.673V0z\" /><path fill=\"currentColor\" fillRule=\"evenodd\" d=\"M4.86 9.099a2.47 2.47 0 0 0-2.365-1.797h-.038C1.097 7.313 0 8.408 0 9.755v3.208h1.44l1.985-1.208v1.204H8v-1.51H4.949v-.633L8 8.96V7.185zm-1.431.875v-.223a.95.95 0 0 0-.953-.943.95.95 0 0 0-.952.943v1.39zM0 18a4 4 0 1 0 8 0 4 4 0 0 0-8 0m4 2.476a2.476 2.476 0 1 0 0-4.952 2.476 2.476 0 0 0 0 4.952\" clipRule=\"evenodd\" /></svg>;\nexport default SvgOryBadgeVertical;","// Copyright © 2024 Ory Corp\n// SPDX-License-Identifier: Apache-2.0\n\nimport OryLogoHorizontal from \"../../assets/ory-badge-horizontal.svg\"\nimport OryLogoVertical from \"../../assets/ory-badge-vertical.svg\"\n\nexport function Badge() {\n return (\n <div\n data-testid=\"ory/card/badge\"\n className=\"absolute border border-ory-border-default bg-ory-background-default p-2 font-bold text-ory-foreground-default max-sm:bottom-0 max-sm:left-8 max-sm:translate-y-full max-sm:rounded-b-branding max-sm:py-[7px] sm:top-8 sm:right-0 sm:translate-x-full sm:rounded-r-branding sm:pl-[7px]\"\n >\n <OryLogoHorizontal width={22} height={8} className=\"sm:hidden\" />\n <OryLogoVertical width={8} height={22} className=\"max-sm:hidden\" />\n </div>\n )\n}\n","// Copyright © 2024 Ory Corp\n// SPDX-License-Identifier: Apache-2.0\n\nimport { OryCardContentProps } from \"@ory/elements-react\"\n\n/**\n * Simply renders the children passed to it.\n *\n * @param props - pass children to render instead of the default Ory Card components\n * @returns\n * @group Components\n * @category Default Components\n */\nexport function DefaultCardContent({ children }: OryCardContentProps) {\n return children\n}\n","// Copyright © 2024 Ory Corp\n// SPDX-License-Identifier: Apache-2.0\n\nimport { FlowType, LoginFlow } from \"@ory/client-fetch\"\nimport {\n ConsentFlow,\n FormState,\n Node,\n useOryConfiguration,\n useOryFlow,\n} from \"@ory/elements-react\"\nimport { useIntl } from \"react-intl\"\nimport { findScreenSelectionButton } from \"../../../../util/nodes\"\nimport {\n findNode,\n hasSingleSignOnNodes,\n nodesToAuthMethodGroups,\n visibleAuthMethodGroups,\n} from \"../../../../util/ui\"\nimport {\n isUiNodeInput,\n UiNodeInput,\n} from \"../../../../util/utilFixSDKTypesHelper\"\nimport { useClientLogout } from \"../../utils/logout\"\nimport { initFlowUrl, restartFlowUrl } from \"../../utils/url\"\n\n/**\n * DefaultCardFooter renders the default footer for the card component based on the current flow type.\n *\n * @returns The default card footer component that renders the appropriate footer based on the current flow type.\n * @group Components\n * @category Default Components\n */\nexport function DefaultCardFooter() {\n const oryFlow = useOryFlow()\n switch (oryFlow.flowType) {\n case FlowType.Login:\n return <LoginCardFooter flow={oryFlow.flow} />\n case FlowType.Registration:\n return <RegistrationCardFooter />\n case FlowType.Recovery:\n return <RecoveryCardFooter />\n case FlowType.Verification:\n return <VerificationCardFooter />\n case FlowType.OAuth2Consent:\n return <ConsentCardFooter flow={oryFlow.flow} />\n default:\n return null\n }\n}\n\nfunction shouldShowLogoutButton(\n flow: LoginFlow,\n formState: FormState,\n authMethods: string[],\n) {\n // Always for refresh flows, as we know there is a session\n if (flow.refresh) {\n return true\n }\n\n // In aal2 flows we sometimes show the logout button\n if (flow.requested_aal === \"aal2\") {\n // Always on the \"method selector\" screen\n if (formState.current === \"select_method\") {\n return true\n }\n // On the \"method active\" screen, if it's a code method\n // If the method is any other than code, we want to show a \"Choose another method\" button\n // This is handled below.\n // TODO: refactor this, to not have this logic in two places\n if (formState.current === \"method_active\" && flow.active === \"code\") {\n return true\n }\n // If there are no other methods, we want to show the logout button\n // This is the case when the user only has one method (e.g. code or totp), set up\n // and the user is on the \"method active\" screen\n // In that case there is no \"select_method\" state, so going back to that screen wouldn't work\n if (formState.current === \"method_active\" && authMethods.length === 1) {\n return true\n }\n }\n return false\n}\n\ntype LoginCardFooterProps = {\n flow: LoginFlow\n}\n\nfunction LoginCardFooter({ flow }: LoginCardFooterProps) {\n const { dispatchFormState, formState } = useOryFlow()\n const config = useOryConfiguration()\n const intl = useIntl()\n\n const authMethods = nodesToAuthMethodGroups(flow.ui.nodes)\n // SSO providers count as a way back to the chooser screen: they render only\n // there, so the back-link must stay while any SSO node is present.\n const hasOtherVisibleMethods =\n visibleAuthMethodGroups(flow.ui.nodes).length > 1 ||\n hasSingleSignOnNodes(flow.ui.nodes)\n\n let returnTo = config.project.default_redirect_url\n if (flow.return_to) {\n returnTo = flow.return_to\n }\n if (!returnTo) {\n returnTo = restartFlowUrl(\n flow,\n `${config.sdk.url}/self-service/${FlowType.Login}/browser`,\n )\n }\n\n if (shouldShowLogoutButton(flow, formState, authMethods)) {\n return <LogoutButton returnTo={returnTo} />\n }\n\n return (\n <>\n {formState.current === \"provide_identifier\" &&\n config.project.registration_enabled &&\n !config.project.hide_registration_link && (\n <span className=\"leading-normal font-normal text-interface-foreground-default-primary antialiased\">\n {intl.formatMessage({\n id: \"login.registration-label\",\n defaultMessage: \"Don't have an account?\",\n })}{\" \"}\n <a\n className=\"text-button-link-brand-brand underline transition-colors hover:text-button-link-brand-brand-hover\"\n href={initFlowUrl(config.sdk.url, \"registration\", flow)}\n data-testid={\"ory/screen/login/action/register\"}\n >\n {intl.formatMessage({\n id: \"login.registration-button\",\n defaultMessage: \"Sign up\",\n })}\n </a>\n </span>\n )}\n {hasOtherVisibleMethods && formState.current === \"method_active\" && (\n <span className=\"leading-normal font-normal text-interface-foreground-default-primary antialiased\">\n <button\n className=\"text-button-link-brand-brand underline transition-colors hover:text-button-link-brand-brand-hover\"\n onClick={() => {\n dispatchFormState({\n type: \"action_clear_active_method\",\n })\n }}\n data-testid={\"ory/screen/login/mfa/action/selectMethod\"}\n >\n {intl.formatMessage({\n id: \"login.2fa.method.go-back\",\n defaultMessage: \"Choose another method\",\n })}\n </button>\n </span>\n )}\n {authMethods.length === 1 &&\n authMethods[0] === \"code\" &&\n formState.current === \"method_active\" && (\n <span className=\"leading-normal font-normal text-interface-foreground-default-primary antialiased\">\n <a\n className=\"text-button-link-brand-brand underline transition-colors hover:text-button-link-brand-brand-hover\"\n href={returnTo}\n data-testid={\"ory/screen/login/action/cancel\"}\n >\n {intl.formatMessage({\n id: \"login.2fa.go-back.link\",\n defaultMessage: \"Go back\",\n })}\n </a>\n </span>\n )}\n </>\n )\n}\n\ntype LogoutButtonProps = {\n returnTo?: string\n}\n\nfunction LogoutButton({ returnTo }: LogoutButtonProps) {\n const config = useOryConfiguration()\n const intl = useIntl()\n const { logoutFlow: logout, didLoad: didLoadLogout } = useClientLogout(config)\n\n return (\n <span className=\"leading-normal font-normal text-interface-foreground-default-primary antialiased\">\n {intl.formatMessage({\n id: \"login.2fa.go-back\",\n defaultMessage: \"Something isn't working?\",\n })}{\" \"}\n <a\n className=\"text-button-link-brand-brand underline transition-colors hover:text-button-link-brand-brand-hover\"\n href={logout ? logout?.logout_url : returnTo}\n data-testid={\n // Only add the test-id when the logout link has loaded.\n didLoadLogout ? \"ory/screen/login/action/logout\" : undefined\n }\n >\n {!didLoadLogout || logout\n ? intl.formatMessage({\n id: \"login.logout-button\",\n defaultMessage: \"Logout\",\n })\n : intl.formatMessage({\n id: \"login.2fa.go-back.link\",\n defaultMessage: \"Go back\",\n })}\n </a>\n </span>\n )\n}\n\nfunction RegistrationCardFooter() {\n const intl = useIntl()\n const { flow, formState, dispatchFormState } = useOryFlow()\n const config = useOryConfiguration()\n const authMethodBlocks = visibleAuthMethodGroups(flow.ui.nodes)\n\n const screenSelectionNode = findScreenSelectionButton(flow.ui.nodes)\n switch (formState.current) {\n case \"method_active\":\n if (!screenSelectionNode || authMethodBlocks.length < 2) {\n return null\n }\n\n return (\n <span className=\"leading-normal font-normal text-interface-foreground-default-primary antialiased\">\n <button\n className=\"text-button-link-brand-brand underline transition-colors hover:text-button-link-brand-brand-hover\"\n onClick={() => {\n dispatchFormState({\n type: \"action_clear_active_method\",\n })\n }}\n data-testid={\"ory/screen/registration/action/selectMethod\"}\n type=\"button\"\n >\n {intl.formatMessage({\n id: \"card.footer.select-another-method\",\n defaultMessage: \"Select another method\",\n })}\n </button>\n </span>\n )\n case \"select_method\":\n default:\n return (\n <span className=\"leading-normal font-normal text-interface-foreground-default-primary antialiased\">\n {intl.formatMessage({\n id: \"registration.login-label\",\n defaultMessage: \"Already have an account?\",\n })}{\" \"}\n <a\n className=\"text-button-link-brand-brand underline transition-colors hover:text-button-link-brand-brand-hover\"\n href={initFlowUrl(config.sdk.url, \"login\", flow)}\n data-testid={\"ory/screen/registration/action/login\"}\n >\n {intl.formatMessage({\n id: \"registration.login-button\",\n defaultMessage: \"Sign in\",\n })}\n </a>\n </span>\n )\n }\n}\n\nfunction RecoveryCardFooter() {\n return null\n}\n\nfunction VerificationCardFooter() {\n return null\n}\n\n/**\n * Props for the ConsentCardFooter component.\n *\n * @hidden\n * @inline\n */\ntype ConsentCardFooterProps = {\n /** The consent flow to render the footer for. */\n flow: ConsentFlow\n}\n\nfunction ConsentCardFooter({ flow }: ConsentCardFooterProps) {\n const rememberNode = findNode(flow.ui.nodes, {\n group: \"oauth2_consent\",\n node_type: \"input\",\n name: \"remember\",\n }) as UiNodeInput\n\n return (\n <div className=\"flex flex-col gap-8\">\n <div>\n <p className=\"leading-normal font-medium text-interface-foreground-default-secondary\">\n Make sure you trust {flow.consent_request.client?.client_name}\n </p>\n <p className=\"leading-normal text-interface-foreground-default-secondary\">\n You may be sharing sensitive information with this site or\n application.\n </p>\n </div>\n {rememberNode && <Node.Checkbox node={rememberNode} />}\n <div className=\"grid grid-cols-1 gap-2 md:grid-cols-2\">\n {flow.ui.nodes\n .filter(\n (n): n is UiNodeInput =>\n n.attributes.node_type === \"input\" &&\n n.attributes.type === \"submit\" &&\n isUiNodeInput(n),\n )\n .map((n) => {\n return <Node.Button key={n.attributes.value} node={n} />\n })}\n </div>\n <p className=\"text-sm\">\n <span className=\"text-interface-foreground-default-tertiary\">\n Authorizing will redirect to{\" \"}\n {flow.consent_request.client?.client_name}\n </span>\n </p>\n </div>\n )\n}\n","// Copyright © 2024 Ory Corp\n// SPDX-License-Identifier: Apache-2.0\n\nimport { UiText } from \"@ory/client-fetch\"\nimport { defineMessages, IntlShape, useIntl } from \"react-intl\"\nimport { isDynamicText } from \"../nodes\"\nimport { isKratosMessageId, kratosMessages } from \"./generated/kratosMessages\"\n\n/**\n * Converts a UiText to a FormattedMessage.\n * The UiText contains the id of the message and the context.\n * The context is used to inject values into the message from Ory, e.g. a timestamp.\n * For example a UI Node from Ory might look like this:\n *\n * ```json\n * {\n * \"type\":\"input\",\n * \"group\":\"default\",\n * \"attributes\": {\n * \"name\":\"traits.email\",\n * \"type\":\"email\",\n * \"required\":true,\n * \"autocomplete\":\"email\",\n * \"disabled\":false,\n * \"node_type\":\"input\"\n * },\n * \"messages\":[],\n * \"meta\": {\n * \"label\": {\n * \"id\":1070002,\n * \"text\":\"E-Mail\",\n * \"type\":\"info\",\n * \"context\":{\n * \"title\":\"E-Mail\"\n * },\n * }\n * }\n * }\n * ```\n *\n * The context has the key \"title\" which matches the formatter template name \"\\{title\\}\"\n * An example translation file would look like this:\n * ```json\n * {\n * \"identities.messages.1070002\": \"{title}\"\n * }\n * ```\n *\n * The formatter would then take the meta.label.id and look for the translation with the key matching the id.\n * It would then replace the template \"\\{title\\}\" with the value from the context with the key \"title\".\n *\n * @param uiText - The UiText is part of the UiNode object sent by Kratos when performing a flow.\n * @param intl - The intl object from react-intl\n * @group Utilities\n */\nexport const uiTextToFormattedMessage = (\n { id, context = {}, text }: Omit<UiText, \"type\">,\n intl: IntlShape,\n) => {\n const contextInjectedMessage = Object.entries(context).reduce(\n (accumulator, [key, value]) => {\n // context might provide an array of objects instead of a single object\n // for example when looking up a recovery code\n if (Array.isArray(value)) {\n return {\n ...accumulator,\n [key]: value,\n [key + \"_list\"]: intl.formatList<string>(value),\n }\n } else if (key.endsWith(\"_unix\")) {\n if (typeof value === \"number\") {\n return {\n ...accumulator,\n [key]: intl.formatDate(new Date(value * 1000)),\n [key + \"_since\"]: intl.formatDateTimeRange(\n new Date(value),\n new Date(),\n ),\n [key + \"_since_minutes\"]: Math.ceil(\n (value - new Date().getTime() / 1000) / 60,\n ).toFixed(0),\n [key + \"_until\"]: intl.formatDateTimeRange(\n new Date(),\n new Date(value),\n ),\n [key + \"_until_minutes\"]: Math.ceil(\n (value - new Date().getTime() / 1000) / 60,\n ).toFixed(0),\n }\n }\n } else if (key === \"property\") {\n if (isKnownPropertyKey(value)) {\n return {\n ...accumulator,\n [key]: intl.formatMessage(propertyMessages[value]),\n }\n } else {\n return {\n ...accumulator,\n [key]: value,\n }\n }\n }\n return {\n ...accumulator,\n [key]: value as string | number,\n }\n },\n {},\n )\n\n if (isKratosMessageId(id)) {\n const hasEmptyArrayContext = Object.values(context).some(\n (v) => Array.isArray(v) && v.length === 0,\n )\n if (hasEmptyArrayContext) {\n return text\n }\n return intl.formatMessage(kratosMessages[id], contextInjectedMessage)\n }\n\n return text\n}\n\nexport function resolvePlaceholder(\n text: UiText,\n intl: ReturnType<typeof useIntl>,\n) {\n const fallback = intl.formatMessage(\n {\n id: \"input.placeholder\",\n defaultMessage: \"Enter your {placeholder}\",\n },\n {\n placeholder: uiTextToFormattedMessage(text, intl),\n },\n )\n if (isDynamicText(text)) {\n const field = text.context.name\n const msg = {\n id: `forms.input.placeholder.${field}`,\n defaultMessage: fallback,\n }\n return intl.formatMessage(msg)\n }\n return fallback\n}\n\nconst KNOWN_PROPERTIES = [\n \"password\",\n \"email\",\n \"phone\",\n \"username\",\n \"identifier\",\n \"code\",\n \"recovery_address\",\n]\n\ntype PropertyKey = (typeof KNOWN_PROPERTIES)[number]\n\nfunction isKnownPropertyKey(key: unknown): key is PropertyKey {\n return typeof key === \"string\" && KNOWN_PROPERTIES.includes(key)\n}\n\nconst propertyMessages = defineMessages<PropertyKey>({\n password: { id: \"property.password\", defaultMessage: \"password\" },\n email: { id: \"property.email\", defaultMessage: \"email\" },\n phone: { id: \"property.phone\", defaultMessage: \"phone\" },\n username: { id: \"property.username\", defaultMessage: \"username\" },\n identifier: {\n id: \"property.identifier\",\n defaultMessage: \"identifier\",\n },\n code: { id: \"property.code\", defaultMessage: \"code\" },\n recovery_address: {\n id: \"property.recovery_address\",\n defaultMessage: \"recovery address\",\n },\n})\n","// Copyright © 2026 Ory Corp\n// SPDX-License-Identifier: Apache-2.0\n\nimport { defineMessages } from \"react-intl\"\n\nconst KNOWN_KRATOS_MESSAGE_IDS = [\n 1010001, 1010002, 1010003, 1010004, 1010005, 1010006, 1010007, 1010008,\n 1010009, 1010010, 1010011, 1010012, 1010013, 1010014, 1010015, 1010016,\n 1010017, 1010018, 1010019, 1010021, 1010022, 1010023, 1010024, 1010025,\n 1040001, 1040002, 1040003, 1040004, 1040005, 1040006, 1040007, 1040008,\n 1040009, 1050001, 1050002, 1050003, 1050004, 1050005, 1050006, 1050007,\n 1050008, 1050009, 1050010, 1050011, 1050012, 1050013, 1050014, 1050015,\n 1050016, 1050017, 1050018, 1050019, 1050020, 1060001, 1060002, 1060003,\n 1060004, 1060005, 1060006, 1060007, 1070001, 1070002, 1070003, 1070004,\n 1070005, 1070006, 1070007, 1070008, 1070009, 1070010, 1070011, 1070012,\n 1070013, 1070014, 1070015, 1070016, 1070017, 1070018, 1080001, 1080002,\n 1080003, 1080004, 1080005, 4000001, 4000002, 4000003, 4000004, 4000005,\n 4000006, 4000007, 4000008, 4000009, 4000010, 4000011, 4000012, 4000013,\n 4000014, 4000015, 4000016, 4000017, 4000018, 4000019, 4000020, 4000021,\n 4000022, 4000023, 4000024, 4000025, 4000026, 4000027, 4000028, 4000029,\n 4000030, 4000031, 4000032, 4000033, 4000034, 4000035, 4000036, 4000037,\n 4000038, 4000039, 4000040, 4000041, 4000042, 4000043, 4000044, 4010001,\n 4010002, 4010003, 4010004, 4010005, 4010006, 4010007, 4010008, 4010009,\n 4010010, 4010011, 4040001, 4040002, 4040003, 4050001, 4050002, 4060001,\n 4060002, 4060004, 4060005, 4060006, 4070001, 4070002, 4070003, 4070005,\n 4070006, 5000001, 5000002, 5000003,\n] as const\n\nexport type KratosMessageId = (typeof KNOWN_KRATOS_MESSAGE_IDS)[number]\n\nexport function isKratosMessageId(id: unknown): id is KratosMessageId {\n return (\n typeof id === \"number\" &&\n KNOWN_KRATOS_MESSAGE_IDS.includes(id as KratosMessageId)\n )\n}\n\nexport const kratosMessages = defineMessages<number>({\n 1010001: {\n id: \"identities.messages.1010001\",\n defaultMessage: `Sign in`,\n },\n 1010002: {\n id: \"identities.messages.1010002\",\n defaultMessage: `Sign in with {provider}`,\n },\n 1010003: {\n id: \"identities.messages.1010003\",\n defaultMessage: `Please confirm this action by verifying that it is you.`,\n },\n 1010004: {\n id: \"identities.messages.1010004\",\n defaultMessage: `Please complete the second authentication challenge.`,\n },\n 1010005: {\n id: \"identities.messages.1010005\",\n defaultMessage: `Verify`,\n },\n 1010006: {\n id: \"identities.messages.1010006\",\n defaultMessage: `Authentication code`,\n },\n 1010007: {\n id: \"identities.messages.1010007\",\n defaultMessage: `Backup recovery code`,\n },\n 1010008: {\n id: \"identities.messages.1010008\",\n defaultMessage: `Continue with hardware key`,\n },\n 1010009: {\n id: \"identities.messages.1010009\",\n defaultMessage: `Continue`,\n },\n 1010010: {\n id: \"identities.messages.1010010\",\n defaultMessage: `Continue`,\n },\n 1010011: {\n id: \"identities.messages.1010011\",\n defaultMessage: `Sign in with a hardware key`,\n },\n 1010012: {\n id: \"identities.messages.1010012\",\n defaultMessage: `Prepare your WebAuthn device (e.g. security key, biometrics scanner, ...) and press continue.`,\n },\n 1010013: {\n id: \"identities.messages.1010013\",\n defaultMessage: `Continue`,\n },\n 1010014: {\n id: \"identities.messages.1010014\",\n defaultMessage: `A code was sent to the address you provided. If you didn't receive it, please check the spelling of the address and try again.`,\n },\n 1010015: {\n id: \"identities.messages.1010015\",\n defaultMessage: `Send sign in code`,\n },\n 1010016: {\n id: \"identities.messages.1010016\",\n defaultMessage: `You tried to sign in with \"{duplicateIdentifier}\", but that email is already used by another account. Sign in to your account with one of the options below to add your account \"{duplicateIdentifier}\" at \"{provider}\" as another way to sign in.`,\n },\n 1010017: {\n id: \"identities.messages.1010017\",\n defaultMessage: `Sign in and link`,\n },\n 1010018: {\n id: \"identities.messages.1010018\",\n defaultMessage: `Confirm with {provider}`,\n },\n 1010019: {\n id: \"identities.messages.1010019\",\n defaultMessage: `Request code to continue`,\n },\n 1010021: {\n id: \"identities.messages.1010021\",\n defaultMessage: `Sign in with passkey`,\n },\n 1010022: {\n id: \"identities.messages.1010022\",\n defaultMessage: `Sign in with password`,\n },\n 1010023: {\n id: \"identities.messages.1010023\",\n defaultMessage: `Send code to {address}`,\n },\n 1010024: {\n id: \"identities.messages.1010024\",\n defaultMessage: `Sign in with a hardware key`,\n },\n 1010025: {\n id: \"identities.messages.1010025\",\n defaultMessage: `A code was sent to your address. If you didn't receive it, please try again.`,\n },\n 1040001: {\n id: \"identities.messages.1040001\",\n defaultMessage: `Sign up`,\n },\n 1040002: {\n id: \"identities.messages.1040002\",\n defaultMessage: `Sign up with {provider}`,\n },\n 1040003: {\n id: \"identities.messages.1040003\",\n defaultMessage: `Continue`,\n },\n 1040004: {\n id: \"identities.messages.1040004\",\n defaultMessage: `Sign up with security key`,\n },\n 1040005: {\n id: \"identities.messages.1040005\",\n defaultMessage: `A code has been sent to the address(es) you provided. If you have not received a message, check the spelling of the address and retry the registration.`,\n },\n 1040006: {\n id: \"identities.messages.1040006\",\n defaultMessage: `Send sign up code`,\n },\n 1040007: {\n id: \"identities.messages.1040007\",\n defaultMessage: `Sign up with passkey`,\n },\n 1040008: {\n id: \"identities.messages.1040008\",\n defaultMessage: `Back`,\n },\n 1040009: {\n id: \"identities.messages.1040009\",\n defaultMessage: `Please choose a credential to authenticate yourself with.`,\n },\n 1050001: {\n id: \"identities.messages.1050001\",\n defaultMessage: `Your changes have been saved!`,\n },\n 1050002: {\n id: \"identities.messages.1050002\",\n defaultMessage: `Link {provider}`,\n },\n 1050003: {\n id: \"identities.messages.1050003\",\n defaultMessage: `Unlink {provider}`,\n },\n 1050004: {\n id: \"identities.messages.1050004\",\n defaultMessage: `Unlink TOTP Authenticator App`,\n },\n 1050005: {\n id: \"identities.messages.1050005\",\n defaultMessage: `Authenticator app QR code`,\n },\n 1050006: {\n id: \"identities.messages.1050006\",\n defaultMessage: `{secret}`,\n },\n 1050007: {\n id: \"identities.messages.1050007\",\n defaultMessage: `Reveal backup recovery codes`,\n },\n 1050008: {\n id: \"identities.messages.1050008\",\n defaultMessage: `Enable`,\n },\n 1050009: {\n id: \"identities.messages.1050009\",\n defaultMessage: `{secret}`,\n },\n 1050010: {\n id: \"identities.messages.1050010\",\n defaultMessage: `These are your back up recovery codes. Please keep them in a safe place!`,\n },\n 1050011: {\n id: \"identities.messages.1050011\",\n defaultMessage: `Confirm backup recovery codes`,\n },\n 1050012: {\n id: \"identities.messages.1050012\",\n defaultMessage: `Add security key`,\n },\n 1050013: {\n id: \"identities.messages.1050013\",\n defaultMessage: `Name of the security key`,\n },\n 1050014: {\n id: \"identities.messages.1050014\",\n defaultMessage: `Secret was used at {used_at, date, long}`,\n },\n 1050015: {\n id: \"identities.messages.1050015\",\n defaultMessage: `{secrets_list}`,\n },\n 1050016: {\n id: \"identities.messages.1050016\",\n defaultMessage: `Disable this method`,\n },\n 1050017: {\n id: \"identities.messages.1050017\",\n defaultMessage: `Authenticator Secret`,\n },\n 1050018: {\n id: \"identities.messages.1050018\",\n defaultMessage: `Remove security key \"{display_name}\"`,\n },\n 1050019: {\n id: \"identities.messages.1050019\",\n defaultMessage: `Add passkey`,\n },\n 1050020: {\n id: \"identities.messages.1050020\",\n defaultMessage: `Remove passkey \"{display_name}\"`,\n },\n 1060001: {\n id: \"identities.messages.1060001\",\n defaultMessage: `You successfully recovered your account. Please change your password or set up an alternative login method (e.g. social sign in) within the next {privileged_session_expires_at_unix_until_minutes} minutes.`,\n },\n 1060002: {\n id: \"identities.messages.1060002\",\n defaultMessage: `An email containing a recovery link has been sent to the email address you provided. If you have not received an email, check the spelling of the address and make sure to use the address you registered with.`,\n },\n 1060003: {\n id: \"identities.messages.1060003\",\n defaultMessage: `An email containing a recovery code has been sent to the email address you provided. If you have not received an email, check the spelling of the address and make sure to use the address you registered with.`,\n },\n 1060004: {\n id: \"identities.messages.1060004\",\n defaultMessage: `A recovery code has been sent to {masked_address}. If you have not received it, check the spelling of the address and make sure to use the address you registered with.`,\n },\n 1060005: {\n id: \"identities.messages.1060005\",\n defaultMessage: `Recover access to your account by providing your recovery address in full.`,\n },\n 1060006: {\n id: \"identities.messages.1060006\",\n defaultMessage: `How do you want to recover your account?`,\n },\n 1060007: {\n id: \"identities.messages.1060007\",\n defaultMessage: `Back`,\n },\n 1070001: {\n id: \"identities.messages.1070001\",\n defaultMessage: `Password`,\n },\n 1070002: {\n id: \"identities.messages.1070002\",\n defaultMessage: `{title}`,\n },\n 1070003: {\n id: \"identities.messages.1070003\",\n defaultMessage: `Save`,\n },\n 1070004: {\n id: \"identities.messages.1070004\",\n defaultMessage: `ID`,\n },\n 1070005: {\n id: \"identities.messages.1070005\",\n defaultMessage: `Submit`,\n },\n 1070006: {\n id: \"identities.messages.1070006\",\n defaultMessage: `Verify code`,\n },\n 1070007: {\n id: \"identities.messages.1070007\",\n defaultMessage: `Email`,\n },\n 1070008: {\n id: \"identities.messages.1070008\",\n defaultMessage: `Resend code`,\n },\n 1070009: {\n id: \"identities.messages.1070009\",\n defaultMessage: `Continue`,\n },\n 1070010: {\n id: \"identities.messages.1070010\",\n defaultMessage: `Recovery code`,\n },\n 1070011: {\n id: \"identities.messages.1070011\",\n defaultMessage: `Verification code`,\n },\n 1070012: {\n id: \"identities.messages.1070012\",\n defaultMessage: `Registration code`,\n },\n 1070013: {\n id: \"identities.messages.1070013\",\n defaultMessage: `Login code`,\n },\n 1070014: {\n id: \"identities.messages.1070014\",\n defaultMessage: `Login and link credential`,\n },\n 1070015: {\n id: \"identities.messages.1070015\",\n defaultMessage: `Please complete the captcha challenge to continue.`,\n },\n 1070016: {\n id: \"identities.messages.1070016\",\n defaultMessage: `Recovery address`,\n },\n 1070017: {\n id: \"identities.messages.1070017\",\n defaultMessage: `Phone number`,\n },\n 1070018: {\n id: \"identities.messages.1070018\",\n defaultMessage: `Email or phone number`,\n },\n 1080001: {\n id: \"identities.messages.1080001\",\n defaultMessage: `An email containing a verification link has been sent to the email address you provided. If you have not received an email, check the spelling of the address and make sure to use the address you registered with.`,\n },\n 1080002: {\n id: \"identities.messages.1080002\",\n defaultMessage: `You successfully verified your email address.`,\n },\n 1080003: {\n id: \"identities.messages.1080003\",\n defaultMessage: `An email containing a verification code has been sent to the email address you provided. If you have not received an email, check the spelling of the address and make sure to use the address you registered with.`,\n },\n 1080004: {\n id: \"identities.messages.1080004\",\n defaultMessage: `A text message containing a verification code has been sent to the phone number you provided. If you have not received a text message, check the spelling of the number and make sure to use the number you registered with.`,\n },\n 1080005: {\n id: \"identities.messages.1080005\",\n defaultMessage: `You successfully verified your phone number.`,\n },\n 4000001: {\n id: \"identities.messages.4000001\",\n defaultMessage: `{reason}`,\n },\n 4000002: {\n id: \"identities.messages.4000002\",\n defaultMessage: `Please enter the {property} and try again.`,\n },\n 4000003: {\n id: \"identities.messages.4000003\",\n defaultMessage: `length must be >= {min_length}, but got {actual_length}`,\n },\n 4000004: {\n id: \"identities.messages.4000004\",\n defaultMessage: `does not match pattern \"{pattern}\"`,\n },\n 4000005: {\n id: \"identities.messages.4000005\",\n defaultMessage: `The password can not be used because {reason}.`,\n },\n 4000006: {\n id: \"identities.messages.4000006\",\n defaultMessage: `The provided credentials are invalid, check for spelling mistakes in your password or username, email address, or phone number.`,\n },\n 4000007: {\n id: \"identities.messages.4000007\",\n defaultMessage: `An account with the same identifier (email, phone, username, ...) exists already.`,\n },\n 4000008: {\n id: \"identities.messages.4000008\",\n defaultMessage: `The provided authentication code is invalid, please try again.`,\n },\n 4000009: {\n id: \"identities.messages.4000009\",\n defaultMessage: `Could not find any login identifiers. Did you forget to set them? This could also be caused by a server misconfiguration.`,\n },\n 4000010: {\n id: \"identities.messages.4000010\",\n defaultMessage: `Account not active yet. Did you forget to verify your email address?`,\n },\n 4000011: {\n id: \"identities.messages.4000011\",\n defaultMessage: `You have no TOTP device set up.`,\n },\n 4000012: {\n id: \"identities.messages.4000012\",\n defaultMessage: `This backup recovery code has already been used.`,\n },\n 4000013: {\n id: \"identities.messages.4000013\",\n defaultMessage: `You have no WebAuthn device set up.`,\n },\n 4000014: {\n id: \"identities.messages.4000014\",\n defaultMessage: `You have no backup recovery codes set up.`,\n },\n 4000015: {\n id: \"identities.messages.4000015\",\n defaultMessage: `This account does not exist or has no security key set up.`,\n },\n 4000016: {\n id: \"identities.messages.4000016\",\n defaultMessage: `The backup recovery code is not valid.`,\n },\n 4000017: {\n id: \"identities.messages.4000017\",\n defaultMessage: `length must be <= {max_length}, but got {actual_length}`,\n },\n 4000018: {\n id: \"identities.messages.4000018\",\n defaultMessage: `must be >= {minimum} but found {actual}`,\n },\n 4000019: {\n id: \"identities.messages.4000019\",\n defaultMessage: `must be > {minimum} but found {actual}`,\n },\n 4000020: {\n id: \"identities.messages.4000020\",\n defaultMessage: `must be <= {maximum} but found {actual}`,\n },\n 4000021: {\n id: \"identities.messages.4000021\",\n defaultMessage: `must be < {maximum} but found {actual}`,\n },\n 4000022: {\n id: \"identities.messages.4000022\",\n defaultMessage: `{actual} not multipleOf {base}`,\n },\n 4000023: {\n id: \"identities.messages.4000023\",\n defaultMessage: `maximum {max_items} items allowed, but found {actual_items} items`,\n },\n 4000024: {\n id: \"identities.messages.4000024\",\n defaultMessage: `minimum {min_items} items allowed, but found {actual_items} items`,\n },\n 4000025: {\n id: \"identities.messages.4000025\",\n defaultMessage: `items at index {index_a} and {index_b} are equal`,\n },\n 4000026: {\n id: \"identities.messages.4000026\",\n defaultMessage: `expected {allowed_types_list}, but got {actual_type}`,\n },\n 4000027: {\n id: \"identities.messages.4000027\",\n defaultMessage: `An account with the same identifier (email, phone, username, ...) exists already. Please sign in to your existing account to link your social profile.`,\n },\n 4000028: {\n id: \"identities.messages.4000028\",\n defaultMessage: `You tried signing in with {credential_identifier_hint} which is already in use by another account. You can sign in using {available_credential_types_list}. You can sign in using one of the following social sign in providers: {available_oidc_providers_list}.`,\n },\n 4000029: {\n id: \"identities.messages.4000029\",\n defaultMessage: `must be equal to constant {expected}`,\n },\n 4000030: {\n id: \"identities.messages.4000030\",\n defaultMessage: `const failed`,\n },\n 4000031: {\n id: \"identities.messages.4000031\",\n defaultMessage: `The password can not be used because it is too similar to the identifier.`,\n },\n 4000032: {\n id: \"identities.messages.4000032\",\n defaultMessage: `The password must be at least {min_length} characters long, but got {actual_length}.`,\n },\n 4000033: {\n id: \"identities.messages.4000033\",\n defaultMessage: `The password must be at most {max_length} characters long, but got {actual_length}.`,\n },\n 4000034: {\n id: \"identities.messages.4000034\",\n defaultMessage: `The password has been