@ory/elements-react 1.0.0-rc.3 → 1.0.0-rc.4
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/CHANGELOG.md +13 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +199 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +197 -47
- package/dist/index.mjs.map +1 -1
- package/dist/theme/default/index.js +153 -121
- package/dist/theme/default/index.js.map +1 -1
- package/dist/theme/default/index.mjs +62 -32
- package/dist/theme/default/index.mjs.map +1 -1
- package/package.json +6 -6
- package/tsconfig.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { UiNodeGroupEnum, isUiNodeInputAttributes, isUiNodeAnchorAttributes, isUiNodeImageAttributes, isUiNodeScriptAttributes, FlowType, getNodeId, Configuration, FrontendApi, isUiNodeTextAttributes, UiNodeInputAttributesTypeEnum, handleContinueWith,
|
|
1
|
+
import { UiNodeGroupEnum, isUiNodeInputAttributes, isUiNodeAnchorAttributes, isUiNodeImageAttributes, isUiNodeScriptAttributes, FlowType, getNodeId, Configuration, FrontendApi, isUiNodeTextAttributes, UiNodeInputAttributesTypeEnum, handleContinueWith, isResponseError as isResponseError$1, loginUrl, settingsUrl, registrationUrl, FetchError, ResponseError, recoveryUrl, instanceOfContinueWithRecoveryUi, verificationUrl as verificationUrl$1 } from '@ory/client-fetch';
|
|
2
2
|
import { createContext, useContext, useRef, useState, useMemo, useReducer, useEffect } from 'react';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
import { useIntl, IntlProvider as IntlProvider$1 } from 'react-intl';
|
|
@@ -320,9 +320,7 @@ function parseStateFromFlow(flow) {
|
|
|
320
320
|
return { current: "method_active", method: "code" };
|
|
321
321
|
} else if (methodWithMessage) {
|
|
322
322
|
return { current: "method_active", method: methodWithMessage.group };
|
|
323
|
-
} else if (flow.flow.active && !["default", "identifier_first"
|
|
324
|
-
flow.flow.active
|
|
325
|
-
)) {
|
|
323
|
+
} else if (flow.flow.active && !["default", "identifier_first"].includes(flow.flow.active)) {
|
|
326
324
|
return { current: "method_active", method: flow.flow.active };
|
|
327
325
|
} else if (isChoosingMethod(flow)) {
|
|
328
326
|
const authMethods = nodesToAuthMethodGroups(flow.flow.ui.nodes);
|
|
@@ -360,14 +358,20 @@ function useFormStateReducer(flow) {
|
|
|
360
358
|
const formStateReducer = (state, action2) => {
|
|
361
359
|
switch (action2.type) {
|
|
362
360
|
case "action_flow_update": {
|
|
363
|
-
if (selectedMethod)
|
|
361
|
+
if (selectedMethod) {
|
|
364
362
|
return { current: "method_active", method: selectedMethod };
|
|
363
|
+
}
|
|
365
364
|
return parseStateFromFlow(action2.flow);
|
|
366
365
|
}
|
|
367
366
|
case "action_select_method": {
|
|
368
367
|
setSelectedMethod(action2.method);
|
|
369
368
|
return { current: "method_active", method: action2.method };
|
|
370
369
|
}
|
|
370
|
+
case "action_clear_active_method": {
|
|
371
|
+
return {
|
|
372
|
+
current: "select_method"
|
|
373
|
+
};
|
|
374
|
+
}
|
|
371
375
|
}
|
|
372
376
|
return state;
|
|
373
377
|
};
|
|
@@ -676,6 +680,134 @@ function replaceWindowFlowId(flow) {
|
|
|
676
680
|
url.searchParams.set("flow", flow);
|
|
677
681
|
window.location.href = url.toString();
|
|
678
682
|
}
|
|
683
|
+
function isGenericErrorResponse(response) {
|
|
684
|
+
return typeof response === "object" && !!response && "error" in response && typeof response.error === "object" && !!response.error && "id" in response.error;
|
|
685
|
+
}
|
|
686
|
+
function isNeedsPrivilegedSessionError(response) {
|
|
687
|
+
return isGenericErrorResponse(response) && response.error.id === "session_refresh_required";
|
|
688
|
+
}
|
|
689
|
+
function isSelfServiceFlowExpiredError(response) {
|
|
690
|
+
return isGenericErrorResponse(response) && response.error.id === "self_service_flow_expired";
|
|
691
|
+
}
|
|
692
|
+
function isBrowserLocationChangeRequired(response) {
|
|
693
|
+
return isGenericErrorResponse(response) && isGenericErrorResponse(response) && response.error.id === "browser_location_change_required";
|
|
694
|
+
}
|
|
695
|
+
function isAddressNotVerified(response) {
|
|
696
|
+
return isGenericErrorResponse(response) && response.error.id === "session_verified_address_required";
|
|
697
|
+
}
|
|
698
|
+
function isCsrfError(response) {
|
|
699
|
+
return isGenericErrorResponse(response) && response.error.id === "security_csrf_violation";
|
|
700
|
+
}
|
|
701
|
+
var isResponseError = (err) => {
|
|
702
|
+
if (err instanceof ResponseError) {
|
|
703
|
+
return true;
|
|
704
|
+
}
|
|
705
|
+
return typeof err === "object" && !!err && "name" in err && err.name === "ResponseError";
|
|
706
|
+
};
|
|
707
|
+
var isFetchError = (err) => {
|
|
708
|
+
return err instanceof FetchError;
|
|
709
|
+
};
|
|
710
|
+
|
|
711
|
+
// src/util/sdk-helpers/urlHelpers.ts
|
|
712
|
+
var verificationUrl = (config) => config.sdk.url + "/self-service/verification/browser";
|
|
713
|
+
var handleFlowError = (opts) => async (err) => {
|
|
714
|
+
var _a;
|
|
715
|
+
if (!isResponseError(err)) {
|
|
716
|
+
if (isFetchError(err)) {
|
|
717
|
+
throw new FetchError(
|
|
718
|
+
err,
|
|
719
|
+
"Unable to call the API endpoint. Ensure that CORS is set up correctly and that you have provided a valid SDK URL to Ory Elements."
|
|
720
|
+
);
|
|
721
|
+
}
|
|
722
|
+
throw err;
|
|
723
|
+
}
|
|
724
|
+
const contentType = err.response.headers.get("content-type") || "";
|
|
725
|
+
if (contentType.includes("application/json")) {
|
|
726
|
+
const body = await toBody(err.response);
|
|
727
|
+
if (isSelfServiceFlowExpiredError(body)) {
|
|
728
|
+
opts.onRestartFlow(body.use_flow_id);
|
|
729
|
+
return;
|
|
730
|
+
} else if (isAddressNotVerified(body)) {
|
|
731
|
+
for (const continueWith of ((_a = body.error.details) == null ? void 0 : _a.continue_with) || []) {
|
|
732
|
+
if (continueWith.action === "show_verification_ui" && continueWith.flow.url) {
|
|
733
|
+
opts.onRedirect(continueWith.flow.url, true);
|
|
734
|
+
return;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
opts.onRedirect(verificationUrl(opts.config), true);
|
|
738
|
+
return;
|
|
739
|
+
} else if (isBrowserLocationChangeRequired(body) && body.redirect_browser_to) {
|
|
740
|
+
opts.onRedirect(body.redirect_browser_to, true);
|
|
741
|
+
return;
|
|
742
|
+
} else if (isNeedsPrivilegedSessionError(body) && body.redirect_browser_to) {
|
|
743
|
+
opts.onRedirect(body.redirect_browser_to, true);
|
|
744
|
+
return;
|
|
745
|
+
} else if (isCsrfError(body)) {
|
|
746
|
+
opts.onRestartFlow();
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
switch (err.response.status) {
|
|
750
|
+
case 404:
|
|
751
|
+
opts.onRestartFlow();
|
|
752
|
+
return;
|
|
753
|
+
case 410:
|
|
754
|
+
opts.onRestartFlow();
|
|
755
|
+
return;
|
|
756
|
+
case 400:
|
|
757
|
+
return opts.onValidationError(
|
|
758
|
+
await err.response.json()
|
|
759
|
+
);
|
|
760
|
+
case 403:
|
|
761
|
+
opts.onRestartFlow();
|
|
762
|
+
return;
|
|
763
|
+
case 422: {
|
|
764
|
+
throw new ResponseError(
|
|
765
|
+
err.response,
|
|
766
|
+
"The API returned an error code indicating a required redirect, but the SDK is outdated and does not know how to handle the action. Received response: " + await err.response.json()
|
|
767
|
+
);
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
throw new ResponseError(
|
|
771
|
+
err.response,
|
|
772
|
+
"The Ory API endpoint returned a response code the SDK does not know how to handle. Please check the network tab for more information. Received response: " + await err.response.json()
|
|
773
|
+
);
|
|
774
|
+
} else if (
|
|
775
|
+
// Not a JSON response? If it's a text response we will return an error informing the user that the response is not JSON.
|
|
776
|
+
contentType.includes("text/") || contentType.includes("html") || contentType.includes("xml")
|
|
777
|
+
) {
|
|
778
|
+
await logResponseError(err.response, true);
|
|
779
|
+
throw new ResponseError(
|
|
780
|
+
err.response,
|
|
781
|
+
`The Ory API endpoint returned an unexpected HTML or text response. Check your console output for details.`
|
|
782
|
+
);
|
|
783
|
+
}
|
|
784
|
+
await logResponseError(err.response, false);
|
|
785
|
+
throw new ResponseError(
|
|
786
|
+
err.response,
|
|
787
|
+
"The Ory API endpoint returned unexpected content type `" + contentType + "`. Check your console output for details."
|
|
788
|
+
);
|
|
789
|
+
};
|
|
790
|
+
async function toBody(response) {
|
|
791
|
+
try {
|
|
792
|
+
return await response.clone().json();
|
|
793
|
+
} catch (e) {
|
|
794
|
+
await logResponseError(response, true, [e]);
|
|
795
|
+
throw new ResponseError(
|
|
796
|
+
response,
|
|
797
|
+
"Unable to decode API response using JSON."
|
|
798
|
+
);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
async function logResponseError(response, printBody, wrap) {
|
|
802
|
+
console.error("Unable to decode API response", {
|
|
803
|
+
response: {
|
|
804
|
+
status: response.status,
|
|
805
|
+
headers: Object.fromEntries(response.headers.entries()),
|
|
806
|
+
body: printBody ? await response.clone().text() : void 0
|
|
807
|
+
},
|
|
808
|
+
errors: wrap
|
|
809
|
+
});
|
|
810
|
+
}
|
|
679
811
|
|
|
680
812
|
// src/util/onSubmitLogin.ts
|
|
681
813
|
async function onSubmitLogin({ flow }, config, {
|
|
@@ -711,7 +843,8 @@ async function onSubmitLogin({ flow }, config, {
|
|
|
711
843
|
flowType: FlowType.Login
|
|
712
844
|
});
|
|
713
845
|
},
|
|
714
|
-
onRedirect
|
|
846
|
+
onRedirect,
|
|
847
|
+
config
|
|
715
848
|
})
|
|
716
849
|
);
|
|
717
850
|
}
|
|
@@ -755,7 +888,8 @@ async function onSubmitRecovery({ flow }, config, {
|
|
|
755
888
|
});
|
|
756
889
|
}
|
|
757
890
|
},
|
|
758
|
-
onRedirect
|
|
891
|
+
onRedirect,
|
|
892
|
+
config
|
|
759
893
|
})
|
|
760
894
|
);
|
|
761
895
|
}
|
|
@@ -804,7 +938,8 @@ async function onSubmitRegistration({ flow }, config, {
|
|
|
804
938
|
flowType: FlowType.Registration
|
|
805
939
|
});
|
|
806
940
|
},
|
|
807
|
-
onRedirect
|
|
941
|
+
onRedirect,
|
|
942
|
+
config
|
|
808
943
|
})
|
|
809
944
|
);
|
|
810
945
|
}
|
|
@@ -843,10 +978,11 @@ async function onSubmitSettings({ flow }, config, {
|
|
|
843
978
|
flowType: FlowType.Settings
|
|
844
979
|
});
|
|
845
980
|
},
|
|
846
|
-
onRedirect
|
|
981
|
+
onRedirect,
|
|
982
|
+
config
|
|
847
983
|
})
|
|
848
984
|
).catch((err) => {
|
|
849
|
-
if (isResponseError(err)) {
|
|
985
|
+
if (isResponseError$1(err)) {
|
|
850
986
|
if (err.response.status === 401) {
|
|
851
987
|
return onRedirect(
|
|
852
988
|
loginUrl(config) + "?return_to=" + settingsUrl(config),
|
|
@@ -876,7 +1012,7 @@ async function onSubmitVerification({ flow }, config, {
|
|
|
876
1012
|
if (useFlowId) {
|
|
877
1013
|
replaceWindowFlowId(useFlowId);
|
|
878
1014
|
} else {
|
|
879
|
-
onRedirect(verificationUrl(config), true);
|
|
1015
|
+
onRedirect(verificationUrl$1(config), true);
|
|
880
1016
|
}
|
|
881
1017
|
},
|
|
882
1018
|
onValidationError: (body2) => {
|
|
@@ -885,7 +1021,8 @@ async function onSubmitVerification({ flow }, config, {
|
|
|
885
1021
|
flowType: FlowType.Verification
|
|
886
1022
|
});
|
|
887
1023
|
},
|
|
888
|
-
onRedirect
|
|
1024
|
+
onRedirect,
|
|
1025
|
+
config
|
|
889
1026
|
})
|
|
890
1027
|
);
|
|
891
1028
|
}
|
|
@@ -1142,7 +1279,20 @@ var NodeInput = ({
|
|
|
1142
1279
|
case UiNodeInputAttributesTypeEnum.Submit:
|
|
1143
1280
|
case UiNodeInputAttributesTypeEnum.Button:
|
|
1144
1281
|
if (isSocial) {
|
|
1145
|
-
return
|
|
1282
|
+
return /* @__PURE__ */ jsx(
|
|
1283
|
+
Node2.OidcButton,
|
|
1284
|
+
{
|
|
1285
|
+
node,
|
|
1286
|
+
attributes: attrs,
|
|
1287
|
+
onClick: () => {
|
|
1288
|
+
setValue(
|
|
1289
|
+
"provider",
|
|
1290
|
+
node.attributes.value
|
|
1291
|
+
);
|
|
1292
|
+
setValue("method", node.group);
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
);
|
|
1146
1296
|
}
|
|
1147
1297
|
if (isResendNode || isScreenSelectionNode) {
|
|
1148
1298
|
return null;
|
|
@@ -1232,6 +1382,37 @@ var Node = ({ node, onClick }) => {
|
|
|
1232
1382
|
}
|
|
1233
1383
|
return null;
|
|
1234
1384
|
};
|
|
1385
|
+
function OryTwoStepCardStateMethodActive({
|
|
1386
|
+
formState
|
|
1387
|
+
}) {
|
|
1388
|
+
const { Form } = useComponents();
|
|
1389
|
+
const { flow, flowType, dispatchFormState } = useOryFlow();
|
|
1390
|
+
const { ui } = flow;
|
|
1391
|
+
const nodeSorter = useNodeSorter();
|
|
1392
|
+
const sortNodes = (a, b) => nodeSorter(a, b, { flowType });
|
|
1393
|
+
const groupsToShow = useNodeGroupsWithVisibleNodes(ui.nodes);
|
|
1394
|
+
const finalNodes = getFinalNodes(groupsToShow, formState.method);
|
|
1395
|
+
return /* @__PURE__ */ jsxs(OryCard, { children: [
|
|
1396
|
+
/* @__PURE__ */ jsx(OryCardHeader, {}),
|
|
1397
|
+
/* @__PURE__ */ jsxs(OryCardContent, { children: [
|
|
1398
|
+
/* @__PURE__ */ jsx(OryCardValidationMessages, {}),
|
|
1399
|
+
/* @__PURE__ */ jsx(
|
|
1400
|
+
OryForm,
|
|
1401
|
+
{
|
|
1402
|
+
"data-testid": `ory/form/methods/local`,
|
|
1403
|
+
onAfterSubmit: handleAfterFormSubmit(dispatchFormState),
|
|
1404
|
+
children: /* @__PURE__ */ jsxs(Form.Group, { children: [
|
|
1405
|
+
ui.nodes.filter(
|
|
1406
|
+
(n) => isUiNodeScriptAttributes(n.attributes) || n.group === UiNodeGroupEnum.Default || n.group === UiNodeGroupEnum.Profile
|
|
1407
|
+
).map((node, k) => /* @__PURE__ */ jsx(Node, { node }, k)),
|
|
1408
|
+
finalNodes.sort(sortNodes).map((node, k) => /* @__PURE__ */ jsx(Node, { node }, k))
|
|
1409
|
+
] })
|
|
1410
|
+
}
|
|
1411
|
+
)
|
|
1412
|
+
] }),
|
|
1413
|
+
/* @__PURE__ */ jsx(OryCardFooter, {})
|
|
1414
|
+
] });
|
|
1415
|
+
}
|
|
1235
1416
|
function OryFormOidcButtons() {
|
|
1236
1417
|
const {
|
|
1237
1418
|
flow: { ui }
|
|
@@ -1262,8 +1443,10 @@ function OryFormOidcButtons() {
|
|
|
1262
1443
|
}
|
|
1263
1444
|
function OryFormSocialButtonsForm() {
|
|
1264
1445
|
const {
|
|
1265
|
-
flow: { ui }
|
|
1446
|
+
flow: { ui },
|
|
1447
|
+
formState
|
|
1266
1448
|
} = useOryFlow();
|
|
1449
|
+
console.log(formState);
|
|
1267
1450
|
const filteredNodes = ui.nodes.filter(
|
|
1268
1451
|
(node) => node.group === UiNodeGroupEnum.Saml || node.group === UiNodeGroupEnum.Oidc
|
|
1269
1452
|
);
|
|
@@ -1272,39 +1455,6 @@ function OryFormSocialButtonsForm() {
|
|
|
1272
1455
|
}
|
|
1273
1456
|
return /* @__PURE__ */ jsx(OryFormProvider, { children: /* @__PURE__ */ jsx(OryForm, { "data-testid": `ory/form/methods/oidc-saml`, children: /* @__PURE__ */ jsx(OryFormOidcButtons, {}) }) });
|
|
1274
1457
|
}
|
|
1275
|
-
function OryTwoStepCardStateMethodActive({
|
|
1276
|
-
formState
|
|
1277
|
-
}) {
|
|
1278
|
-
const { Form } = useComponents();
|
|
1279
|
-
const { flow, flowType, dispatchFormState } = useOryFlow();
|
|
1280
|
-
const { ui } = flow;
|
|
1281
|
-
const nodeSorter = useNodeSorter();
|
|
1282
|
-
const sortNodes = (a, b) => nodeSorter(a, b, { flowType });
|
|
1283
|
-
const groupsToShow = useNodeGroupsWithVisibleNodes(ui.nodes);
|
|
1284
|
-
const finalNodes = getFinalNodes(groupsToShow, formState.method);
|
|
1285
|
-
const selectedMethodIsSocial = formState.method === UiNodeGroupEnum.Oidc || formState.method === UiNodeGroupEnum.Saml;
|
|
1286
|
-
return /* @__PURE__ */ jsxs(OryCard, { children: [
|
|
1287
|
-
/* @__PURE__ */ jsx(OryCardHeader, {}),
|
|
1288
|
-
/* @__PURE__ */ jsxs(OryCardContent, { children: [
|
|
1289
|
-
/* @__PURE__ */ jsx(OryCardValidationMessages, {}),
|
|
1290
|
-
selectedMethodIsSocial && /* @__PURE__ */ jsx(OryFormSocialButtonsForm, {}),
|
|
1291
|
-
/* @__PURE__ */ jsx(
|
|
1292
|
-
OryForm,
|
|
1293
|
-
{
|
|
1294
|
-
"data-testid": `ory/form/methods/local`,
|
|
1295
|
-
onAfterSubmit: handleAfterFormSubmit(dispatchFormState),
|
|
1296
|
-
children: /* @__PURE__ */ jsxs(Form.Group, { children: [
|
|
1297
|
-
ui.nodes.filter(
|
|
1298
|
-
(n) => isUiNodeScriptAttributes(n.attributes) || n.group === UiNodeGroupEnum.Default || n.group === UiNodeGroupEnum.Profile
|
|
1299
|
-
).map((node, k) => /* @__PURE__ */ jsx(Node, { node }, k)),
|
|
1300
|
-
finalNodes.sort(sortNodes).map((node, k) => /* @__PURE__ */ jsx(Node, { node }, k))
|
|
1301
|
-
] })
|
|
1302
|
-
}
|
|
1303
|
-
)
|
|
1304
|
-
] }),
|
|
1305
|
-
/* @__PURE__ */ jsx(OryCardFooter, {})
|
|
1306
|
-
] });
|
|
1307
|
-
}
|
|
1308
1458
|
function OryTwoStepCardStateProvideIdentifier() {
|
|
1309
1459
|
const { Form, Card } = useComponents();
|
|
1310
1460
|
const { flowType, flow, dispatchFormState } = useOryFlow();
|