@authowl/react 0.18.1 → 0.18.3
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.cjs +36 -9
- package/dist/index.d.cts +3 -6
- package/dist/index.d.ts +3 -6
- package/dist/index.js +36 -9
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -625,7 +625,21 @@ var KNOWN_METHODS = [
|
|
|
625
625
|
function emailAutocomplete(isPasskeyHost) {
|
|
626
626
|
return isPasskeyHost ? "email webauthn" : "email";
|
|
627
627
|
}
|
|
628
|
-
function
|
|
628
|
+
function passkeyReachableFrom(authBaseUrl, pageHost, relyingPartyId) {
|
|
629
|
+
if (pageHost === void 0) return true;
|
|
630
|
+
let rpId = relyingPartyId ?? void 0;
|
|
631
|
+
if (!rpId) {
|
|
632
|
+
if (!authBaseUrl) return true;
|
|
633
|
+
try {
|
|
634
|
+
rpId = new URL(authBaseUrl).hostname;
|
|
635
|
+
} catch {
|
|
636
|
+
return true;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
if (rpId !== "localhost" && !rpId.includes(".")) return false;
|
|
640
|
+
return pageHost === rpId || pageHost.endsWith(`.${rpId}`);
|
|
641
|
+
}
|
|
642
|
+
function resolveSignInMethods(config, pageHost) {
|
|
629
643
|
const methods = config?.enabledMethods ?? ["password"];
|
|
630
644
|
const social = config?.socialProviders ?? [];
|
|
631
645
|
const has = (m) => methods.includes(m);
|
|
@@ -635,7 +649,11 @@ function resolveSignInMethods(config) {
|
|
|
635
649
|
const magicLink = capabilities.magicLinkSignIn;
|
|
636
650
|
const emailOtp = capabilities.emailOtpSignIn && !capabilities.totp && !capabilities.mfaRequired;
|
|
637
651
|
const phoneOtp = capabilities.phoneSignIn;
|
|
638
|
-
const passkey = capabilities.passkeySignIn
|
|
652
|
+
const passkey = capabilities.passkeySignIn && passkeyReachableFrom(
|
|
653
|
+
config?.authBaseUrl,
|
|
654
|
+
pageHost,
|
|
655
|
+
config?.authentication?.passkey?.relyingPartyId
|
|
656
|
+
);
|
|
639
657
|
const sso = has("sso");
|
|
640
658
|
const renderable = password || username || magicLink || emailOtp || phoneOtp || passkey || sso || social.length > 0;
|
|
641
659
|
const emptyReason = renderable ? null : methods.length > 0 ? "unsupported" : "none";
|
|
@@ -688,8 +706,15 @@ function hasUsableSession(store) {
|
|
|
688
706
|
const data = store.getSnapshot().data;
|
|
689
707
|
return Boolean(data?.user && data.session.pendingMfaEnrollment !== true);
|
|
690
708
|
}
|
|
709
|
+
function isHeldAtEnrollment(store) {
|
|
710
|
+
const data = store.getSnapshot().data;
|
|
711
|
+
return Boolean(data?.user && data.session.pendingMfaEnrollment === true);
|
|
712
|
+
}
|
|
691
713
|
function waitForUsableSession(store) {
|
|
692
|
-
|
|
714
|
+
const outcome = () => isHeldAtEnrollment(store) ? "held" : "settled";
|
|
715
|
+
if (hasUsableSession(store) || isHeldAtEnrollment(store)) {
|
|
716
|
+
return Promise.resolve(outcome());
|
|
717
|
+
}
|
|
693
718
|
return new Promise((resolve) => {
|
|
694
719
|
let settled = false;
|
|
695
720
|
let unsubscribe = () => {
|
|
@@ -699,23 +724,22 @@ function waitForUsableSession(store) {
|
|
|
699
724
|
settled = true;
|
|
700
725
|
window.clearTimeout(timeout);
|
|
701
726
|
unsubscribe();
|
|
702
|
-
resolve();
|
|
727
|
+
resolve(outcome());
|
|
703
728
|
};
|
|
704
729
|
const timeout = window.setTimeout(finish, SESSION_SETTLE_TIMEOUT_MS);
|
|
705
730
|
unsubscribe = store.subscribe(() => {
|
|
706
|
-
if (hasUsableSession(store)) finish();
|
|
731
|
+
if (hasUsableSession(store) || isHeldAtEnrollment(store)) finish();
|
|
707
732
|
});
|
|
708
|
-
if (hasUsableSession(store)) finish();
|
|
733
|
+
if (hasUsableSession(store) || isHeldAtEnrollment(store)) finish();
|
|
709
734
|
});
|
|
710
735
|
}
|
|
711
736
|
async function finishSignIn(opts) {
|
|
737
|
+
if (await waitForUsableSession(opts.sessionStore) === "held") return;
|
|
712
738
|
opts.onSignedIn?.();
|
|
713
739
|
if (safeRedirect(opts.redirectTo)) {
|
|
714
740
|
await new Promise(() => {
|
|
715
741
|
});
|
|
716
|
-
return;
|
|
717
742
|
}
|
|
718
|
-
await waitForUsableSession(opts.sessionStore);
|
|
719
743
|
}
|
|
720
744
|
|
|
721
745
|
// src/components/use-submit-action.ts
|
|
@@ -3623,7 +3647,10 @@ function SignIn({
|
|
|
3623
3647
|
const [challenge, setChallenge] = React16.useState(false);
|
|
3624
3648
|
const mfaEnrolment = useConfirmedMfaPending();
|
|
3625
3649
|
const emailRef = React16.useRef(null);
|
|
3626
|
-
const plan = resolveSignInMethods(
|
|
3650
|
+
const plan = resolveSignInMethods(
|
|
3651
|
+
config,
|
|
3652
|
+
typeof window === "undefined" ? void 0 : window.location.hostname
|
|
3653
|
+
);
|
|
3627
3654
|
usePasskeyAutofill({
|
|
3628
3655
|
enabled: credentialMode === "email" && plan.autofillHost !== null,
|
|
3629
3656
|
redirectTo,
|
package/dist/index.d.cts
CHANGED
|
@@ -311,12 +311,9 @@ type SignInPlan = {
|
|
|
311
311
|
* passkeys inline. One place owns the token string.
|
|
312
312
|
*/
|
|
313
313
|
declare function emailAutocomplete(isPasskeyHost: boolean): string;
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
* rather than showing nothing.
|
|
318
|
-
*/
|
|
319
|
-
declare function resolveSignInMethods(config: PublicConfig | null): SignInPlan;
|
|
314
|
+
declare function resolveSignInMethods(config: PublicConfig | null,
|
|
315
|
+
/** The hostname the form is rendering on; omit when it is not knowable. */
|
|
316
|
+
pageHost?: string): SignInPlan;
|
|
320
317
|
|
|
321
318
|
type SignInProps = {
|
|
322
319
|
redirectTo?: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -311,12 +311,9 @@ type SignInPlan = {
|
|
|
311
311
|
* passkeys inline. One place owns the token string.
|
|
312
312
|
*/
|
|
313
313
|
declare function emailAutocomplete(isPasskeyHost: boolean): string;
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
* rather than showing nothing.
|
|
318
|
-
*/
|
|
319
|
-
declare function resolveSignInMethods(config: PublicConfig | null): SignInPlan;
|
|
314
|
+
declare function resolveSignInMethods(config: PublicConfig | null,
|
|
315
|
+
/** The hostname the form is rendering on; omit when it is not knowable. */
|
|
316
|
+
pageHost?: string): SignInPlan;
|
|
320
317
|
|
|
321
318
|
type SignInProps = {
|
|
322
319
|
redirectTo?: string;
|
package/dist/index.js
CHANGED
|
@@ -544,7 +544,21 @@ var KNOWN_METHODS = [
|
|
|
544
544
|
function emailAutocomplete(isPasskeyHost) {
|
|
545
545
|
return isPasskeyHost ? "email webauthn" : "email";
|
|
546
546
|
}
|
|
547
|
-
function
|
|
547
|
+
function passkeyReachableFrom(authBaseUrl, pageHost, relyingPartyId) {
|
|
548
|
+
if (pageHost === void 0) return true;
|
|
549
|
+
let rpId = relyingPartyId ?? void 0;
|
|
550
|
+
if (!rpId) {
|
|
551
|
+
if (!authBaseUrl) return true;
|
|
552
|
+
try {
|
|
553
|
+
rpId = new URL(authBaseUrl).hostname;
|
|
554
|
+
} catch {
|
|
555
|
+
return true;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
if (rpId !== "localhost" && !rpId.includes(".")) return false;
|
|
559
|
+
return pageHost === rpId || pageHost.endsWith(`.${rpId}`);
|
|
560
|
+
}
|
|
561
|
+
function resolveSignInMethods(config, pageHost) {
|
|
548
562
|
const methods = config?.enabledMethods ?? ["password"];
|
|
549
563
|
const social = config?.socialProviders ?? [];
|
|
550
564
|
const has = (m) => methods.includes(m);
|
|
@@ -554,7 +568,11 @@ function resolveSignInMethods(config) {
|
|
|
554
568
|
const magicLink = capabilities.magicLinkSignIn;
|
|
555
569
|
const emailOtp = capabilities.emailOtpSignIn && !capabilities.totp && !capabilities.mfaRequired;
|
|
556
570
|
const phoneOtp = capabilities.phoneSignIn;
|
|
557
|
-
const passkey = capabilities.passkeySignIn
|
|
571
|
+
const passkey = capabilities.passkeySignIn && passkeyReachableFrom(
|
|
572
|
+
config?.authBaseUrl,
|
|
573
|
+
pageHost,
|
|
574
|
+
config?.authentication?.passkey?.relyingPartyId
|
|
575
|
+
);
|
|
558
576
|
const sso = has("sso");
|
|
559
577
|
const renderable = password || username || magicLink || emailOtp || phoneOtp || passkey || sso || social.length > 0;
|
|
560
578
|
const emptyReason = renderable ? null : methods.length > 0 ? "unsupported" : "none";
|
|
@@ -607,8 +625,15 @@ function hasUsableSession(store) {
|
|
|
607
625
|
const data = store.getSnapshot().data;
|
|
608
626
|
return Boolean(data?.user && data.session.pendingMfaEnrollment !== true);
|
|
609
627
|
}
|
|
628
|
+
function isHeldAtEnrollment(store) {
|
|
629
|
+
const data = store.getSnapshot().data;
|
|
630
|
+
return Boolean(data?.user && data.session.pendingMfaEnrollment === true);
|
|
631
|
+
}
|
|
610
632
|
function waitForUsableSession(store) {
|
|
611
|
-
|
|
633
|
+
const outcome = () => isHeldAtEnrollment(store) ? "held" : "settled";
|
|
634
|
+
if (hasUsableSession(store) || isHeldAtEnrollment(store)) {
|
|
635
|
+
return Promise.resolve(outcome());
|
|
636
|
+
}
|
|
612
637
|
return new Promise((resolve) => {
|
|
613
638
|
let settled = false;
|
|
614
639
|
let unsubscribe = () => {
|
|
@@ -618,23 +643,22 @@ function waitForUsableSession(store) {
|
|
|
618
643
|
settled = true;
|
|
619
644
|
window.clearTimeout(timeout);
|
|
620
645
|
unsubscribe();
|
|
621
|
-
resolve();
|
|
646
|
+
resolve(outcome());
|
|
622
647
|
};
|
|
623
648
|
const timeout = window.setTimeout(finish, SESSION_SETTLE_TIMEOUT_MS);
|
|
624
649
|
unsubscribe = store.subscribe(() => {
|
|
625
|
-
if (hasUsableSession(store)) finish();
|
|
650
|
+
if (hasUsableSession(store) || isHeldAtEnrollment(store)) finish();
|
|
626
651
|
});
|
|
627
|
-
if (hasUsableSession(store)) finish();
|
|
652
|
+
if (hasUsableSession(store) || isHeldAtEnrollment(store)) finish();
|
|
628
653
|
});
|
|
629
654
|
}
|
|
630
655
|
async function finishSignIn(opts) {
|
|
656
|
+
if (await waitForUsableSession(opts.sessionStore) === "held") return;
|
|
631
657
|
opts.onSignedIn?.();
|
|
632
658
|
if (safeRedirect(opts.redirectTo)) {
|
|
633
659
|
await new Promise(() => {
|
|
634
660
|
});
|
|
635
|
-
return;
|
|
636
661
|
}
|
|
637
|
-
await waitForUsableSession(opts.sessionStore);
|
|
638
662
|
}
|
|
639
663
|
|
|
640
664
|
// src/components/use-submit-action.ts
|
|
@@ -3545,7 +3569,10 @@ function SignIn({
|
|
|
3545
3569
|
const [challenge, setChallenge] = React16.useState(false);
|
|
3546
3570
|
const mfaEnrolment = useConfirmedMfaPending();
|
|
3547
3571
|
const emailRef = React16.useRef(null);
|
|
3548
|
-
const plan = resolveSignInMethods(
|
|
3572
|
+
const plan = resolveSignInMethods(
|
|
3573
|
+
config,
|
|
3574
|
+
typeof window === "undefined" ? void 0 : window.location.hostname
|
|
3575
|
+
);
|
|
3549
3576
|
usePasskeyAutofill({
|
|
3550
3577
|
enabled: credentialMode === "email" && plan.autofillHost !== null,
|
|
3551
3578
|
redirectTo,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@authowl/react",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.3",
|
|
4
4
|
"description": "React provider, hooks, and drop-in components for AuthOwl, the multi-tenant auth SaaS.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"LICENSE"
|
|
48
48
|
],
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@authowl/core": "0.15.
|
|
50
|
+
"@authowl/core": "0.15.1"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
53
|
"react": ">=18",
|