@dloizides/auth-web 1.8.1 → 1.9.0
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.d.mts +15 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +33 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +33 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +110 -110
package/dist/index.d.mts
CHANGED
|
@@ -345,6 +345,13 @@ interface PasskeyLoginLabels {
|
|
|
345
345
|
errorCancelled: string;
|
|
346
346
|
/** Error banner when the ceremony failed. */
|
|
347
347
|
errorFailed: string;
|
|
348
|
+
/**
|
|
349
|
+
* The "try another way" affordance shown after an in-page ceremony error — it
|
|
350
|
+
* hands off to the Keycloak-hosted passkey/password flow. This is the seam that
|
|
351
|
+
* rescues a user whose credential is only enrolled in Keycloak (not the in-page
|
|
352
|
+
* RP store): the in-page ceremony can't see it, so they fall back to KC.
|
|
353
|
+
*/
|
|
354
|
+
tryAnotherWay: string;
|
|
348
355
|
}
|
|
349
356
|
/** Strings rendered by `<PasskeySettingsCard>` — the account passkey card. */
|
|
350
357
|
interface PasskeySettingsLabels {
|
|
@@ -1301,6 +1308,7 @@ declare const AuthTestIds: {
|
|
|
1301
1308
|
readonly passkeyLogin: "auth-passkey-login";
|
|
1302
1309
|
readonly passkeyLoginButton: "auth-passkey-login-button";
|
|
1303
1310
|
readonly passkeyLoginError: "auth-passkey-login-error";
|
|
1311
|
+
readonly passkeyLoginFallback: "auth-passkey-login-fallback";
|
|
1304
1312
|
readonly passkeySettings: "auth-passkey-settings";
|
|
1305
1313
|
readonly passkeySettingsAdd: "auth-passkey-settings-add";
|
|
1306
1314
|
readonly passkeySettingsSuccess: "auth-passkey-settings-success";
|
|
@@ -1768,6 +1776,13 @@ interface UsePasskeyCeremonyResult {
|
|
|
1768
1776
|
isSupported: boolean;
|
|
1769
1777
|
/** Start the ceremony (or redirect-fallback when the RP is off / unsupported). */
|
|
1770
1778
|
start: () => void;
|
|
1779
|
+
/**
|
|
1780
|
+
* Hand off to the legacy Keycloak redirect explicitly. Wired to the "try
|
|
1781
|
+
* another way" affordance a surface shows after an in-page error — the escape
|
|
1782
|
+
* hatch for a credential enrolled only in Keycloak (invisible to the in-page
|
|
1783
|
+
* RP store), which the in-page ceremony cannot use.
|
|
1784
|
+
*/
|
|
1785
|
+
fallbackToRedirect: () => void;
|
|
1771
1786
|
/** Clear a terminal state so the affordance can be retried. */
|
|
1772
1787
|
reset: () => void;
|
|
1773
1788
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -345,6 +345,13 @@ interface PasskeyLoginLabels {
|
|
|
345
345
|
errorCancelled: string;
|
|
346
346
|
/** Error banner when the ceremony failed. */
|
|
347
347
|
errorFailed: string;
|
|
348
|
+
/**
|
|
349
|
+
* The "try another way" affordance shown after an in-page ceremony error — it
|
|
350
|
+
* hands off to the Keycloak-hosted passkey/password flow. This is the seam that
|
|
351
|
+
* rescues a user whose credential is only enrolled in Keycloak (not the in-page
|
|
352
|
+
* RP store): the in-page ceremony can't see it, so they fall back to KC.
|
|
353
|
+
*/
|
|
354
|
+
tryAnotherWay: string;
|
|
348
355
|
}
|
|
349
356
|
/** Strings rendered by `<PasskeySettingsCard>` — the account passkey card. */
|
|
350
357
|
interface PasskeySettingsLabels {
|
|
@@ -1301,6 +1308,7 @@ declare const AuthTestIds: {
|
|
|
1301
1308
|
readonly passkeyLogin: "auth-passkey-login";
|
|
1302
1309
|
readonly passkeyLoginButton: "auth-passkey-login-button";
|
|
1303
1310
|
readonly passkeyLoginError: "auth-passkey-login-error";
|
|
1311
|
+
readonly passkeyLoginFallback: "auth-passkey-login-fallback";
|
|
1304
1312
|
readonly passkeySettings: "auth-passkey-settings";
|
|
1305
1313
|
readonly passkeySettingsAdd: "auth-passkey-settings-add";
|
|
1306
1314
|
readonly passkeySettingsSuccess: "auth-passkey-settings-success";
|
|
@@ -1768,6 +1776,13 @@ interface UsePasskeyCeremonyResult {
|
|
|
1768
1776
|
isSupported: boolean;
|
|
1769
1777
|
/** Start the ceremony (or redirect-fallback when the RP is off / unsupported). */
|
|
1770
1778
|
start: () => void;
|
|
1779
|
+
/**
|
|
1780
|
+
* Hand off to the legacy Keycloak redirect explicitly. Wired to the "try
|
|
1781
|
+
* another way" affordance a surface shows after an in-page error — the escape
|
|
1782
|
+
* hatch for a credential enrolled only in Keycloak (invisible to the in-page
|
|
1783
|
+
* RP store), which the in-page ceremony cannot use.
|
|
1784
|
+
*/
|
|
1785
|
+
fallbackToRedirect: () => void;
|
|
1771
1786
|
/** Clear a terminal state so the affordance can be retried. */
|
|
1772
1787
|
reset: () => void;
|
|
1773
1788
|
}
|
package/dist/index.js
CHANGED
|
@@ -236,7 +236,8 @@ var DEFAULT_PASSKEY_LOGIN_LABELS = {
|
|
|
236
236
|
signInButton: "Sign in with a passkey",
|
|
237
237
|
signInHint: "Use your fingerprint, face, or security key to sign in",
|
|
238
238
|
errorCancelled: "Passkey sign-in was cancelled. You can try again or sign in another way.",
|
|
239
|
-
errorFailed: "Passkey sign-in didn't work. Try again, or sign in another way."
|
|
239
|
+
errorFailed: "Passkey sign-in didn't work. Try again, or sign in another way.",
|
|
240
|
+
tryAnotherWay: "Sign in another way"
|
|
240
241
|
};
|
|
241
242
|
var DEFAULT_PASSKEY_SETTINGS_LABELS = {
|
|
242
243
|
title: "Passkeys",
|
|
@@ -338,6 +339,7 @@ var AuthTestIds = {
|
|
|
338
339
|
passkeyLogin: "auth-passkey-login",
|
|
339
340
|
passkeyLoginButton: "auth-passkey-login-button",
|
|
340
341
|
passkeyLoginError: "auth-passkey-login-error",
|
|
342
|
+
passkeyLoginFallback: "auth-passkey-login-fallback",
|
|
341
343
|
// Passkey settings card
|
|
342
344
|
passkeySettings: "auth-passkey-settings",
|
|
343
345
|
passkeySettingsAdd: "auth-passkey-settings-add",
|
|
@@ -2746,6 +2748,10 @@ function usePasskeyCeremony(optionsArg) {
|
|
|
2746
2748
|
const envelope = await optionsResponse.json();
|
|
2747
2749
|
const credential = await runCeremony(mode, envelope);
|
|
2748
2750
|
if (credential === null) {
|
|
2751
|
+
if (mode === "login" /* Login */) {
|
|
2752
|
+
redirectFallback(mode, returnUrl);
|
|
2753
|
+
return;
|
|
2754
|
+
}
|
|
2749
2755
|
setStatus("error" /* Error */);
|
|
2750
2756
|
setError(ERROR_FAILED);
|
|
2751
2757
|
return;
|
|
@@ -2777,13 +2783,16 @@ function usePasskeyCeremony(optionsArg) {
|
|
|
2777
2783
|
}
|
|
2778
2784
|
})();
|
|
2779
2785
|
}, [isSupported, mode, returnUrl, succeed]);
|
|
2786
|
+
const fallbackToRedirect = react.useCallback(() => {
|
|
2787
|
+
redirectFallback(mode, returnUrl);
|
|
2788
|
+
}, [mode, returnUrl]);
|
|
2780
2789
|
const reset = react.useCallback(() => {
|
|
2781
2790
|
setStatus("idle" /* Idle */);
|
|
2782
2791
|
setError(null);
|
|
2783
2792
|
}, []);
|
|
2784
2793
|
return react.useMemo(
|
|
2785
|
-
() => ({ status, error, isSupported, start, reset }),
|
|
2786
|
-
[status, error, isSupported, start, reset]
|
|
2794
|
+
() => ({ status, error, isSupported, start, fallbackToRedirect, reset }),
|
|
2795
|
+
[status, error, isSupported, start, fallbackToRedirect, reset]
|
|
2787
2796
|
);
|
|
2788
2797
|
}
|
|
2789
2798
|
var DEFAULT_RETURN_URL = "/";
|
|
@@ -2802,14 +2811,27 @@ function PasskeyLoginButton({
|
|
|
2802
2811
|
const ceremony = usePasskeyCeremony({ mode: "login" /* Login */, returnUrl });
|
|
2803
2812
|
const error = ceremony.error ?? readPasskeyError();
|
|
2804
2813
|
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { testID: withTestIdPrefix(AuthTestIds.passkeyLogin, testIdPrefix), children: [
|
|
2805
|
-
error !== null ? /* @__PURE__ */ jsxRuntime.
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2814
|
+
error !== null ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2815
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2816
|
+
reactNative.Text,
|
|
2817
|
+
{
|
|
2818
|
+
style: styles3.errorText,
|
|
2819
|
+
testID: withTestIdPrefix(AuthTestIds.passkeyLoginError, testIdPrefix),
|
|
2820
|
+
children: error === "cancelled" ? labels.errorCancelled : labels.errorFailed
|
|
2821
|
+
}
|
|
2822
|
+
),
|
|
2823
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2824
|
+
reactNative.TouchableOpacity,
|
|
2825
|
+
{
|
|
2826
|
+
accessibilityHint: labels.tryAnotherWay,
|
|
2827
|
+
accessibilityLabel: labels.tryAnotherWay,
|
|
2828
|
+
accessibilityRole: "button",
|
|
2829
|
+
testID: withTestIdPrefix(AuthTestIds.passkeyLoginFallback, testIdPrefix),
|
|
2830
|
+
onPress: () => ceremony.fallbackToRedirect(),
|
|
2831
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles3.linkText, children: labels.tryAnotherWay })
|
|
2832
|
+
}
|
|
2833
|
+
)
|
|
2834
|
+
] }) : null,
|
|
2813
2835
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2814
2836
|
reactNative.TouchableOpacity,
|
|
2815
2837
|
{
|