@ory/elements-react 1.0.0-next.15 → 1.0.0-next.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
- import { UiNodeGroupEnum, isUiNodeInputAttributes, isUiNodeAnchorAttributes, isUiNodeImageAttributes, isUiNodeScriptAttributes, isUiNodeTextAttributes, UiNodeInputAttributesTypeEnum, FlowType, Configuration, FrontendApi, handleContinueWith, settingsUrl, handleFlowError, isResponseError, loginUrl, recoveryUrl, verificationUrl, registrationUrl } from '@ory/client-fetch';
2
- import { createContext, useContext, useRef, useEffect, useState, useReducer, useMemo } from 'react';
1
+ import { UiNodeGroupEnum, isUiNodeInputAttributes, isUiNodeAnchorAttributes, isUiNodeImageAttributes, isUiNodeScriptAttributes, isUiNodeTextAttributes, FlowType, handleFlowError, loginUrl, handleContinueWith, recoveryUrl, instanceOfContinueWithRecoveryUi, registrationUrl, settingsUrl, isResponseError, verificationUrl, UiNodeInputAttributesTypeEnum, Configuration, FrontendApi } from '@ory/client-fetch';
2
+ import { createContext, useContext, useState, useMemo, useReducer, useRef, useEffect } from 'react';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
  import { useIntl, IntlProvider as IntlProvider$1 } from 'react-intl';
5
- import { useForm, FormProvider, useFormContext } from 'react-hook-form';
5
+ import { useFormContext, useForm, FormProvider } from 'react-hook-form';
6
6
 
7
7
  // src/context/component.tsx
8
8
  var ComponentContext = createContext({
@@ -105,20 +105,34 @@ function getFinalNodes(uniqueGroups, selectedGroup) {
105
105
  }
106
106
 
107
107
  // src/context/form-state.ts
108
+ function findMethodWithMessage(nodes) {
109
+ var _a;
110
+ return (_a = nodes == null ? void 0 : nodes.filter((n) => !["default", "identifier_first"].includes(n.group))) == null ? void 0 : _a.find((node) => {
111
+ var _a2;
112
+ return ((_a2 = node.messages) == null ? void 0 : _a2.length) > 0;
113
+ });
114
+ }
108
115
  function parseStateFromFlow(flow) {
116
+ var _a;
109
117
  switch (flow.flowType) {
110
118
  case FlowType.Registration:
111
- case FlowType.Login:
119
+ case FlowType.Login: {
120
+ const methodWithMessage = findMethodWithMessage(flow.flow.ui.nodes);
112
121
  if (flow.flow.active == "link_recovery") {
113
122
  return { current: "method_active", method: "link" };
114
123
  } else if (flow.flow.active == "code_recovery") {
115
124
  return { current: "method_active", method: "code" };
125
+ } else if (methodWithMessage) {
126
+ return { current: "method_active", method: methodWithMessage.group };
127
+ } else if (flow.flow.active && !["default", "identifier_first", "oidc"].includes(flow.flow.active)) {
128
+ return { current: "method_active", method: flow.flow.active };
116
129
  } else if (isChoosingMethod(flow.flow.ui.nodes)) {
117
130
  return { current: "select_method" };
118
- } else if (flow.flow.active) {
119
- return { current: "method_active", method: flow.flow.active };
131
+ } else if ((_a = flow.flow.ui.messages) == null ? void 0 : _a.some((m) => m.id === 1010016)) {
132
+ return { current: "select_method" };
120
133
  }
121
134
  return { current: "provide_identifier" };
135
+ }
122
136
  case FlowType.Recovery:
123
137
  case FlowType.Verification:
124
138
  if (flow.flow.active === "code" || flow.flow.active === "link") {
@@ -425,7 +439,8 @@ var en_default = {
425
439
  "settings.passkey.title": "Manage Passkeys",
426
440
  "settings.passkey.description": "Manage your passkey settings",
427
441
  "settings.passkey.info": "Manage your passkey settings",
428
- "card.footer.select-another-method": "Select another method"
442
+ "card.footer.select-another-method": "Select another method",
443
+ "account-linking.title": "Link account"
429
444
  };
430
445
 
431
446
  // src/locales/de.json
@@ -671,7 +686,8 @@ var de_default = {
671
686
  "settings.title-totp": "Verwalten Sie die 2FA TOTP Authenticator-App",
672
687
  "settings.title-webauthn": "Hardware-Token verwalten",
673
688
  "settings.webauthn.info": "Hardware-Tokens werden f\xFCr die Zweitfaktor-Authentifizierung oder als Erstfaktor-Authentifizierung mit Passkeys verwendet",
674
- "card.footer.select-another-method": "Eine andere Methode verwenden"
689
+ "card.footer.select-another-method": "Eine andere Methode verwenden",
690
+ "account-linking.title": "Account Verbinden"
675
691
  };
676
692
 
677
693
  // src/locales/es.json
@@ -917,7 +933,8 @@ var es_default = {
917
933
  "settings.title-totp": "",
918
934
  "settings.title-webauthn": "",
919
935
  "settings.webauthn.info": "",
920
- "card.footer.select-another-method": ""
936
+ "card.footer.select-another-method": "",
937
+ "account-linking.title": ""
921
938
  };
922
939
 
923
940
  // src/locales/fr.json
@@ -1163,7 +1180,8 @@ var fr_default = {
1163
1180
  "settings.webauthn.description": "",
1164
1181
  "settings.webauthn.info": "",
1165
1182
  "settings.webauthn.title": "",
1166
- "card.footer.select-another-method": ""
1183
+ "card.footer.select-another-method": "",
1184
+ "account-linking.title": ""
1167
1185
  };
1168
1186
 
1169
1187
  // src/locales/nl.json
@@ -1409,7 +1427,8 @@ var nl_default = {
1409
1427
  "settings.webauthn.description": "",
1410
1428
  "settings.webauthn.info": "",
1411
1429
  "settings.webauthn.title": "",
1412
- "card.footer.select-another-method": ""
1430
+ "card.footer.select-another-method": "",
1431
+ "account-linking.title": ""
1413
1432
  };
1414
1433
 
1415
1434
  // src/locales/pl.json
@@ -1655,7 +1674,8 @@ var pl_default = {
1655
1674
  "settings.webauthn.description": "",
1656
1675
  "settings.webauthn.info": "",
1657
1676
  "settings.webauthn.title": "",
1658
- "card.footer.select-another-method": ""
1677
+ "card.footer.select-another-method": "",
1678
+ "account-linking.title": ""
1659
1679
  };
1660
1680
 
1661
1681
  // src/locales/pt.json
@@ -1901,7 +1921,8 @@ var pt_default = {
1901
1921
  "settings.webauthn.description": "",
1902
1922
  "settings.webauthn.info": "",
1903
1923
  "settings.webauthn.title": "",
1904
- "card.footer.select-another-method": ""
1924
+ "card.footer.select-another-method": "",
1925
+ "account-linking.title": ""
1905
1926
  };
1906
1927
 
1907
1928
  // src/locales/sv.json
@@ -2147,7 +2168,8 @@ var sv_default = {
2147
2168
  "settings.webauthn.description": "Hantera inst\xE4llningarna f\xF6r din maskinvarutoken",
2148
2169
  "settings.webauthn.info": "H\xE5rdvarutokens anv\xE4nds f\xF6r andrafaktorsautentisering eller som f\xF6rstafaktor med l\xF6senordsnycklar",
2149
2170
  "settings.webauthn.title": "Hantera maskinvarutokens",
2150
- "card.footer.select-another-method": "V\xE4lj en annan metod"
2171
+ "card.footer.select-another-method": "V\xE4lj en annan metod",
2172
+ "account-linking.title": "L\xE4nka ditt konto"
2151
2173
  };
2152
2174
 
2153
2175
  // src/locales/index.ts
@@ -2285,16 +2307,34 @@ async function onSubmitRecovery({ config, flow }, {
2285
2307
  onRedirect(recoveryUrl(config), true);
2286
2308
  },
2287
2309
  onValidationError: (body2) => {
2288
- setFlowContainer({
2289
- flow: body2,
2290
- flowType: FlowType.Recovery,
2291
- config
2292
- });
2310
+ if ("error" in body2) {
2311
+ handleContinueWithRecoveryUIError(body2.error, config, onRedirect);
2312
+ return;
2313
+ } else {
2314
+ setFlowContainer({
2315
+ flow: body2,
2316
+ flowType: FlowType.Recovery,
2317
+ config
2318
+ });
2319
+ }
2293
2320
  },
2294
2321
  onRedirect
2295
2322
  })
2296
2323
  );
2297
2324
  }
2325
+ function handleContinueWithRecoveryUIError(error, config, onRedirect) {
2326
+ if ("continue_with" in error.details && Array.isArray(error.details.continue_with)) {
2327
+ const continueWithRecovery = error.details.continue_with.find(instanceOfContinueWithRecoveryUi);
2328
+ if ((continueWithRecovery == null ? void 0 : continueWithRecovery.action) === "show_recovery_ui") {
2329
+ onRedirect(
2330
+ config.project.recovery_ui_url + "?flow=" + (continueWithRecovery == null ? void 0 : continueWithRecovery.flow.id),
2331
+ false
2332
+ );
2333
+ return;
2334
+ }
2335
+ }
2336
+ onRedirect(recoveryUrl(config), true);
2337
+ }
2298
2338
  async function onSubmitRegistration({ config, flow }, {
2299
2339
  setFlowContainer,
2300
2340
  body,
@@ -2425,20 +2465,22 @@ function computeDefaultValues(nodes) {
2425
2465
  return nodes.reduce((acc, node) => {
2426
2466
  const attrs = node.attributes;
2427
2467
  if (isUiNodeInputAttributes(attrs)) {
2428
- if (attrs.name === "method" || attrs.type === "submit" || typeof attrs.value === "undefined")
2468
+ if (attrs.name === "method" || attrs.type === "submit" || typeof attrs.value === "undefined") {
2429
2469
  return acc;
2430
- const unrolled = unrollTrait({
2431
- name: attrs.name,
2432
- value: attrs.value
2433
- });
2434
- Object.assign(acc, unrolled != null ? unrolled : { [attrs.name]: attrs.value });
2470
+ }
2471
+ return unrollTrait(
2472
+ {
2473
+ name: attrs.name,
2474
+ value: attrs.value
2475
+ },
2476
+ acc
2477
+ );
2435
2478
  }
2436
2479
  return acc;
2437
2480
  }, {});
2438
2481
  }
2439
2482
  function unrollTrait(input, output = {}) {
2440
2483
  const keys = input.name.split(".");
2441
- if (!keys.length) return void 0;
2442
2484
  let current = output;
2443
2485
  keys.forEach((key, index) => {
2444
2486
  if (!key) return;
@@ -2534,8 +2576,10 @@ var NodeInput = ({
2534
2576
  //
2535
2577
  ...attrs
2536
2578
  } = attributes;
2579
+ const isResendNode = ((_a = node.meta.label) == null ? void 0 : _a.id) === 1070008;
2580
+ const isScreenSelectionNode = "name" in node.attributes && node.attributes.name === "screen";
2537
2581
  const setFormValue = () => {
2538
- if (attrs.value) {
2582
+ if (attrs.value && !(isResendNode || isScreenSelectionNode)) {
2539
2583
  setValue(attrs.name, attrs.value);
2540
2584
  }
2541
2585
  };
@@ -2560,8 +2604,6 @@ var NodeInput = ({
2560
2604
  };
2561
2605
  const isSocial = (attrs.name === "provider" || attrs.name === "link") && node.group === "oidc";
2562
2606
  const isPinCodeInput = attrs.name === "code" && node.group === "code" || attrs.name === "totp_code" && node.group === "totp";
2563
- const isResendNode = ((_a = node.meta.label) == null ? void 0 : _a.id) === 1070008;
2564
- const isScreenSelectionNode = "name" in node.attributes && node.attributes.name === "screen";
2565
2607
  switch (attributes.type) {
2566
2608
  case UiNodeInputAttributesTypeEnum.Submit:
2567
2609
  case UiNodeInputAttributesTypeEnum.Button:
@@ -2633,6 +2675,51 @@ function OryFormGroups({ children, groups }) {
2633
2675
  return /* @__PURE__ */ jsx(Node, { node }, k);
2634
2676
  }) });
2635
2677
  }
2678
+
2679
+ // src/components/form/form-resolver.ts
2680
+ function isCodeResendRequest(data) {
2681
+ var _a;
2682
+ return (_a = data.email) != null ? _a : data.resend;
2683
+ }
2684
+ function useOryFormResolver() {
2685
+ const flowContainer = useOryFlow();
2686
+ return (data) => {
2687
+ if (flowContainer.formState.current === "method_active") {
2688
+ if (data.method === "code" && !data.code && !isCodeResendRequest(data)) {
2689
+ return {
2690
+ values: data,
2691
+ errors: {
2692
+ code: {
2693
+ id: 4000002,
2694
+ context: {
2695
+ property: "code"
2696
+ },
2697
+ type: "error",
2698
+ text: "Property code is missing"
2699
+ }
2700
+ }
2701
+ };
2702
+ }
2703
+ }
2704
+ return {
2705
+ values: data,
2706
+ errors: {}
2707
+ };
2708
+ };
2709
+ }
2710
+ function OryFormProvider({
2711
+ children,
2712
+ nodes
2713
+ }) {
2714
+ const flowContainer = useOryFlow();
2715
+ const defaultNodes = nodes ? flowContainer.flow.ui.nodes.filter((node) => node.group === UiNodeGroupEnum.Default).concat(nodes) : flowContainer.flow.ui.nodes;
2716
+ const methods = useForm({
2717
+ // TODO: Generify this, so we have typesafety in the submit handler.
2718
+ defaultValues: computeDefaultValues(defaultNodes),
2719
+ resolver: useOryFormResolver()
2720
+ });
2721
+ return /* @__PURE__ */ jsx(FormProvider, { ...methods, children });
2722
+ }
2636
2723
  function OryFormOidcButtons({
2637
2724
  children,
2638
2725
  hideDivider
@@ -2678,7 +2765,7 @@ function OryFormSocialButtonsForm() {
2678
2765
  if (filteredNodes.length === 0) {
2679
2766
  return null;
2680
2767
  }
2681
- return /* @__PURE__ */ jsx(OryForm, { children: /* @__PURE__ */ jsx(OryFormOidcButtons, {}) });
2768
+ return /* @__PURE__ */ jsx(OryFormProvider, { children: /* @__PURE__ */ jsx(OryForm, { children: /* @__PURE__ */ jsx(OryFormOidcButtons, {}) }) });
2682
2769
  }
2683
2770
  function OryForm({ children, onAfterSubmit }) {
2684
2771
  var _a;
@@ -2777,6 +2864,12 @@ function OryForm({ children, onAfterSubmit }) {
2777
2864
  break;
2778
2865
  }
2779
2866
  }
2867
+ if ("password" in data) {
2868
+ methods.setValue("password", "");
2869
+ }
2870
+ if ("code" in data) {
2871
+ methods.setValue("code", "");
2872
+ }
2780
2873
  onAfterSubmit == null ? void 0 : onAfterSubmit(data.method);
2781
2874
  };
2782
2875
  const hasMethods = flowContainer.flow.ui.nodes.filter((node) => {
@@ -2822,7 +2915,7 @@ function OryForm({ children, onAfterSubmit }) {
2822
2915
  }
2823
2916
  );
2824
2917
  }
2825
- var messageIdsToHide = [1040009, 1060003, 1080003, 1010014, 1040005];
2918
+ var messageIdsToHide = [1040009, 1060003, 1080003, 1010014, 1040005, 1010016];
2826
2919
  function OryCardValidationMessages({ ...props }) {
2827
2920
  var _a;
2828
2921
  const { flow } = useOryFlow();
@@ -2835,18 +2928,6 @@ function OryCardValidationMessages({ ...props }) {
2835
2928
  }
2836
2929
  return /* @__PURE__ */ jsx(Message.Root, { ...props, children: messages == null ? void 0 : messages.map((message) => /* @__PURE__ */ jsx(Message.Content, { message }, message.id)) });
2837
2930
  }
2838
- function OryFormProvider({
2839
- children,
2840
- nodes
2841
- }) {
2842
- const flowContainer = useOryFlow();
2843
- const defaultNodes = nodes ? flowContainer.flow.ui.nodes.filter((node) => node.group === UiNodeGroupEnum.Default).concat(nodes) : flowContainer.flow.ui.nodes;
2844
- const methods = useForm({
2845
- // TODO: Generify this, so we have typesafety in the submit handler.
2846
- defaultValues: computeDefaultValues(defaultNodes)
2847
- });
2848
- return /* @__PURE__ */ jsx(FormProvider, { ...methods, children });
2849
- }
2850
2931
  function OryFormSection({ children, nodes }) {
2851
2932
  const { Card } = useComponents();
2852
2933
  return /* @__PURE__ */ jsx(OryFormProvider, { nodes, children: /* @__PURE__ */ jsx(OryForm, { children: /* @__PURE__ */ jsx(Card.SettingsSection, { children }) }) });