@douvery/auth 0.2.1 → 0.3.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/README.md +199 -2
- package/dist/index.d.ts +107 -1
- package/dist/index.js +187 -0
- package/dist/index.js.map +1 -1
- package/dist/qwik/index.d.ts +135 -1
- package/dist/qwik/index.js +296 -24
- package/dist/qwik/index.js.map +1 -1
- package/dist/react/index.d.ts +144 -1
- package/dist/react/index.js +373 -45
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
package/dist/qwik/index.js
CHANGED
|
@@ -626,6 +626,171 @@ var DouveryAuthClient = class {
|
|
|
626
626
|
}
|
|
627
627
|
return tokens.accessToken;
|
|
628
628
|
}
|
|
629
|
+
// ============================================
|
|
630
|
+
// Navigation Methods
|
|
631
|
+
// ============================================
|
|
632
|
+
/** Redirect to select/switch account */
|
|
633
|
+
selectAccount(options = {}) {
|
|
634
|
+
const url = this.buildSelectAccountUrl(options);
|
|
635
|
+
this.navigate(url, options);
|
|
636
|
+
}
|
|
637
|
+
/** Build select-account URL without redirecting */
|
|
638
|
+
buildSelectAccountUrl(options = {}) {
|
|
639
|
+
const params = new URLSearchParams();
|
|
640
|
+
if (options.returnTo) params.set("continue", options.returnTo);
|
|
641
|
+
if (options.clientId) params.set("client_id", options.clientId);
|
|
642
|
+
if (options.loginHint) params.set("login_hint", options.loginHint);
|
|
643
|
+
return this.createAuthUrl("/select-account", params);
|
|
644
|
+
}
|
|
645
|
+
/** Redirect to add another account (multi-session) */
|
|
646
|
+
addAccount(options = {}) {
|
|
647
|
+
const url = this.buildAddAccountUrl(options);
|
|
648
|
+
this.navigate(url, options);
|
|
649
|
+
}
|
|
650
|
+
/** Build add-account URL without redirecting */
|
|
651
|
+
buildAddAccountUrl(options = {}) {
|
|
652
|
+
const params = new URLSearchParams({ add_account: "true" });
|
|
653
|
+
if (options.returnTo) params.set("continue", options.returnTo);
|
|
654
|
+
if (options.clientId) params.set("client_id", options.clientId);
|
|
655
|
+
if (options.loginHint) params.set("login_hint", options.loginHint);
|
|
656
|
+
return this.createAuthUrl("/login", params);
|
|
657
|
+
}
|
|
658
|
+
/** Redirect to register a new account */
|
|
659
|
+
register(options = {}) {
|
|
660
|
+
const url = this.buildRegisterUrl(options);
|
|
661
|
+
this.navigate(url, options);
|
|
662
|
+
}
|
|
663
|
+
/** Build register URL without redirecting */
|
|
664
|
+
buildRegisterUrl(options = {}) {
|
|
665
|
+
const params = new URLSearchParams();
|
|
666
|
+
if (options.returnTo) params.set("continue", options.returnTo);
|
|
667
|
+
if (options.clientId) params.set("client_id", options.clientId);
|
|
668
|
+
if (options.email) params.set("email", options.email);
|
|
669
|
+
if (options.firstName) params.set("first_name", options.firstName);
|
|
670
|
+
if (options.lastName) params.set("last_name", options.lastName);
|
|
671
|
+
if (options.uiLocales) params.set("ui_locales", options.uiLocales);
|
|
672
|
+
return this.createAuthUrl("/register", params);
|
|
673
|
+
}
|
|
674
|
+
/** Redirect to recover account (forgot password) */
|
|
675
|
+
recoverAccount(options = {}) {
|
|
676
|
+
const url = this.buildRecoverAccountUrl(options);
|
|
677
|
+
this.navigate(url, options);
|
|
678
|
+
}
|
|
679
|
+
/** Build recover-account URL without redirecting */
|
|
680
|
+
buildRecoverAccountUrl(options = {}) {
|
|
681
|
+
const params = new URLSearchParams();
|
|
682
|
+
if (options.returnTo) params.set("continue", options.returnTo);
|
|
683
|
+
if (options.clientId) params.set("client_id", options.clientId);
|
|
684
|
+
if (options.email) params.set("email", options.email);
|
|
685
|
+
return this.createAuthUrl("/recover-account", params);
|
|
686
|
+
}
|
|
687
|
+
/** Redirect to verify account (email verification) */
|
|
688
|
+
verifyAccount(options = {}) {
|
|
689
|
+
const url = this.buildVerifyAccountUrl(options);
|
|
690
|
+
this.navigate(url, options);
|
|
691
|
+
}
|
|
692
|
+
/** Build verify-account URL without redirecting */
|
|
693
|
+
buildVerifyAccountUrl(options = {}) {
|
|
694
|
+
const params = new URLSearchParams();
|
|
695
|
+
if (options.returnTo) params.set("continue", options.returnTo);
|
|
696
|
+
if (options.clientId) params.set("client_id", options.clientId);
|
|
697
|
+
if (options.email) params.set("email", options.email);
|
|
698
|
+
return this.createAuthUrl("/verify-account", params);
|
|
699
|
+
}
|
|
700
|
+
/** Redirect to upgrade account (guest → full account) */
|
|
701
|
+
upgradeAccount(options = {}) {
|
|
702
|
+
const url = this.buildUpgradeAccountUrl(options);
|
|
703
|
+
this.navigate(url, options);
|
|
704
|
+
}
|
|
705
|
+
/** Build upgrade-account URL without redirecting */
|
|
706
|
+
buildUpgradeAccountUrl(options = {}) {
|
|
707
|
+
const params = new URLSearchParams();
|
|
708
|
+
if (options.returnTo) params.set("continue", options.returnTo);
|
|
709
|
+
if (options.clientId) params.set("client_id", options.clientId);
|
|
710
|
+
if (options.scopes?.length) params.set("scope", options.scopes.join(" "));
|
|
711
|
+
return this.createAuthUrl("/upgrade-account", params);
|
|
712
|
+
}
|
|
713
|
+
/** Redirect to passkey setup */
|
|
714
|
+
setupPasskey(options = {}) {
|
|
715
|
+
const url = this.buildSetupPasskeyUrl(options);
|
|
716
|
+
this.navigate(url, options);
|
|
717
|
+
}
|
|
718
|
+
/** Build setup-passkey URL without redirecting */
|
|
719
|
+
buildSetupPasskeyUrl(options = {}) {
|
|
720
|
+
const params = new URLSearchParams();
|
|
721
|
+
if (options.returnTo) params.set("continue", options.returnTo);
|
|
722
|
+
if (options.clientId) params.set("client_id", options.clientId);
|
|
723
|
+
return this.createAuthUrl("/setup-passkey", params);
|
|
724
|
+
}
|
|
725
|
+
/** Redirect to address setup */
|
|
726
|
+
setupAddress(options = {}) {
|
|
727
|
+
const url = this.buildSetupAddressUrl(options);
|
|
728
|
+
this.navigate(url, options);
|
|
729
|
+
}
|
|
730
|
+
/** Build setup-address URL without redirecting */
|
|
731
|
+
buildSetupAddressUrl(options = {}) {
|
|
732
|
+
const params = new URLSearchParams();
|
|
733
|
+
if (options.returnTo) params.set("continue", options.returnTo);
|
|
734
|
+
if (options.clientId) params.set("client_id", options.clientId);
|
|
735
|
+
return this.createAuthUrl("/setup-address", params);
|
|
736
|
+
}
|
|
737
|
+
/** Build a login URL without redirecting (useful for links/buttons) */
|
|
738
|
+
buildLoginUrl(options = {}) {
|
|
739
|
+
const params = new URLSearchParams();
|
|
740
|
+
if (options.returnTo) params.set("continue", options.returnTo);
|
|
741
|
+
if (options.loginHint) params.set("email", options.loginHint);
|
|
742
|
+
if (options.prompt) params.set("prompt", options.prompt);
|
|
743
|
+
if (options.uiLocales) params.set("ui_locales", options.uiLocales);
|
|
744
|
+
return this.createAuthUrl("/login", params);
|
|
745
|
+
}
|
|
746
|
+
/** Build a logout URL without redirecting */
|
|
747
|
+
buildLogoutUrl(options = {}) {
|
|
748
|
+
const params = new URLSearchParams();
|
|
749
|
+
if (options.returnTo) params.set("continue", options.returnTo);
|
|
750
|
+
return this.createAuthUrl("/logout", params);
|
|
751
|
+
}
|
|
752
|
+
/** Revoke a token (access or refresh) */
|
|
753
|
+
async revokeToken(options = {}) {
|
|
754
|
+
this.log("Revoking token...");
|
|
755
|
+
const token = options.token ?? (await this.tokenManager.getTokens())?.accessToken;
|
|
756
|
+
if (!token) {
|
|
757
|
+
throw new AuthError("invalid_token", "No token to revoke");
|
|
758
|
+
}
|
|
759
|
+
const revokeUrl = `${this.config.issuer}/oauth/revoke`;
|
|
760
|
+
const body = new URLSearchParams({
|
|
761
|
+
token,
|
|
762
|
+
client_id: this.config.clientId
|
|
763
|
+
});
|
|
764
|
+
if (options.tokenTypeHint) {
|
|
765
|
+
body.set("token_type_hint", options.tokenTypeHint);
|
|
766
|
+
}
|
|
767
|
+
const response = await fetch(revokeUrl, {
|
|
768
|
+
method: "POST",
|
|
769
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
770
|
+
body
|
|
771
|
+
});
|
|
772
|
+
if (!response.ok) {
|
|
773
|
+
const error = await response.json().catch(() => ({}));
|
|
774
|
+
throw new AuthError(
|
|
775
|
+
error.error ?? "server_error",
|
|
776
|
+
error.error_description ?? "Token revocation failed"
|
|
777
|
+
);
|
|
778
|
+
}
|
|
779
|
+
this.log("Token revoked successfully");
|
|
780
|
+
}
|
|
781
|
+
/** Check if the user's session is expired */
|
|
782
|
+
isSessionExpired() {
|
|
783
|
+
if (!this.state.tokens) return true;
|
|
784
|
+
return isTokenExpired(this.state.tokens.accessToken);
|
|
785
|
+
}
|
|
786
|
+
/** Check if user needs email verification */
|
|
787
|
+
needsEmailVerification() {
|
|
788
|
+
return this.state.user?.emailVerified === false;
|
|
789
|
+
}
|
|
790
|
+
/** Check if user is a guest account */
|
|
791
|
+
isGuestAccount() {
|
|
792
|
+
return this.state.user?.accountType === "guest";
|
|
793
|
+
}
|
|
629
794
|
tokenSetToInfo(tokenSet) {
|
|
630
795
|
return {
|
|
631
796
|
accessToken: tokenSet.access_token,
|
|
@@ -636,6 +801,28 @@ var DouveryAuthClient = class {
|
|
|
636
801
|
scope: tokenSet.scope?.split(" ") ?? []
|
|
637
802
|
};
|
|
638
803
|
}
|
|
804
|
+
/** Build an AuthUrl object for a given path and params */
|
|
805
|
+
createAuthUrl(path, params) {
|
|
806
|
+
const query = params.toString();
|
|
807
|
+
const url = `${this.config.issuer}${path}${query ? `?${query}` : ""}`;
|
|
808
|
+
return {
|
|
809
|
+
url,
|
|
810
|
+
redirect: () => {
|
|
811
|
+
window.location.href = url;
|
|
812
|
+
},
|
|
813
|
+
open: () => {
|
|
814
|
+
return window.open(url, "_blank");
|
|
815
|
+
}
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
/** Navigate to an auth URL, respecting openInNewTab option */
|
|
819
|
+
navigate(authUrl, options) {
|
|
820
|
+
if (options.openInNewTab) {
|
|
821
|
+
authUrl.open();
|
|
822
|
+
} else {
|
|
823
|
+
authUrl.redirect();
|
|
824
|
+
}
|
|
825
|
+
}
|
|
639
826
|
async fetchUser(accessToken) {
|
|
640
827
|
const discovery = await this.getDiscovery();
|
|
641
828
|
const response = await fetch(discovery.userinfo_endpoint, {
|
|
@@ -734,30 +921,38 @@ function createDouveryAuth(config) {
|
|
|
734
921
|
return new DouveryAuthClient(config);
|
|
735
922
|
}
|
|
736
923
|
var DouveryAuthContext = createContextId("douvery-auth");
|
|
737
|
-
var DouveryAuthProvider = component$(
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
isInitialized
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
924
|
+
var DouveryAuthProvider = component$(
|
|
925
|
+
({ config }) => {
|
|
926
|
+
const client = createDouveryAuth(config);
|
|
927
|
+
const state = useSignal(client.getState());
|
|
928
|
+
const isInitialized = useSignal(false);
|
|
929
|
+
const isLoading = useSignal(false);
|
|
930
|
+
const error = useSignal(null);
|
|
931
|
+
useContextProvider(DouveryAuthContext, {
|
|
932
|
+
state,
|
|
933
|
+
isInitialized,
|
|
934
|
+
isLoading,
|
|
935
|
+
error,
|
|
936
|
+
client
|
|
750
937
|
});
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
}
|
|
938
|
+
useVisibleTask$(() => {
|
|
939
|
+
client.initialize().then(() => {
|
|
940
|
+
isInitialized.value = true;
|
|
941
|
+
state.value = client.getState();
|
|
942
|
+
}).catch((err) => {
|
|
943
|
+
error.value = err instanceof Error ? err : new Error(String(err));
|
|
944
|
+
});
|
|
945
|
+
const unsubscribe = client.subscribe((event) => {
|
|
946
|
+
state.value = client.getState();
|
|
947
|
+
if (event.type === "LOGIN_ERROR" || event.type === "LOGOUT_ERROR" || event.type === "TOKEN_REFRESH_ERROR") {
|
|
948
|
+
error.value = event.error;
|
|
949
|
+
}
|
|
950
|
+
});
|
|
951
|
+
return () => unsubscribe();
|
|
756
952
|
});
|
|
757
|
-
return
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
});
|
|
953
|
+
return /* @__PURE__ */ jsx(Slot, {});
|
|
954
|
+
}
|
|
955
|
+
);
|
|
761
956
|
function useDouveryAuth() {
|
|
762
957
|
return useContext(DouveryAuthContext);
|
|
763
958
|
}
|
|
@@ -805,9 +1000,86 @@ function useAuthActions() {
|
|
|
805
1000
|
isLoading.value = false;
|
|
806
1001
|
}
|
|
807
1002
|
};
|
|
808
|
-
|
|
1003
|
+
const selectAccount = (options) => {
|
|
1004
|
+
client.selectAccount(options);
|
|
1005
|
+
};
|
|
1006
|
+
const addAccount = (options) => {
|
|
1007
|
+
client.addAccount(options);
|
|
1008
|
+
};
|
|
1009
|
+
const register = (options) => {
|
|
1010
|
+
client.register(options);
|
|
1011
|
+
};
|
|
1012
|
+
const recoverAccount = (options) => {
|
|
1013
|
+
client.recoverAccount(options);
|
|
1014
|
+
};
|
|
1015
|
+
const verifyAccount = (options) => {
|
|
1016
|
+
client.verifyAccount(options);
|
|
1017
|
+
};
|
|
1018
|
+
const upgradeAccount = (options) => {
|
|
1019
|
+
client.upgradeAccount(options);
|
|
1020
|
+
};
|
|
1021
|
+
const setupPasskey = (options) => {
|
|
1022
|
+
client.setupPasskey(options);
|
|
1023
|
+
};
|
|
1024
|
+
const setupAddress = (options) => {
|
|
1025
|
+
client.setupAddress(options);
|
|
1026
|
+
};
|
|
1027
|
+
const revokeToken = async (options) => {
|
|
1028
|
+
isLoading.value = true;
|
|
1029
|
+
error.value = null;
|
|
1030
|
+
try {
|
|
1031
|
+
await client.revokeToken(options);
|
|
1032
|
+
} catch (err) {
|
|
1033
|
+
error.value = err instanceof Error ? err : new Error(String(err));
|
|
1034
|
+
throw err;
|
|
1035
|
+
} finally {
|
|
1036
|
+
isLoading.value = false;
|
|
1037
|
+
}
|
|
1038
|
+
};
|
|
1039
|
+
return {
|
|
1040
|
+
login,
|
|
1041
|
+
logout,
|
|
1042
|
+
selectAccount,
|
|
1043
|
+
addAccount,
|
|
1044
|
+
register,
|
|
1045
|
+
recoverAccount,
|
|
1046
|
+
verifyAccount,
|
|
1047
|
+
upgradeAccount,
|
|
1048
|
+
setupPasskey,
|
|
1049
|
+
setupAddress,
|
|
1050
|
+
revokeToken,
|
|
1051
|
+
isLoading
|
|
1052
|
+
};
|
|
1053
|
+
}
|
|
1054
|
+
function useAuthUrls() {
|
|
1055
|
+
const { client } = useDouveryAuth();
|
|
1056
|
+
return {
|
|
1057
|
+
loginUrl: (options) => client.buildLoginUrl(options),
|
|
1058
|
+
logoutUrl: (options) => client.buildLogoutUrl(options),
|
|
1059
|
+
selectAccountUrl: (options) => client.buildSelectAccountUrl(options),
|
|
1060
|
+
addAccountUrl: (options) => client.buildAddAccountUrl(options),
|
|
1061
|
+
registerUrl: (options) => client.buildRegisterUrl(options),
|
|
1062
|
+
recoverAccountUrl: (options) => client.buildRecoverAccountUrl(options),
|
|
1063
|
+
verifyAccountUrl: (options) => client.buildVerifyAccountUrl(options),
|
|
1064
|
+
upgradeAccountUrl: (options) => client.buildUpgradeAccountUrl(options),
|
|
1065
|
+
setupPasskeyUrl: (options) => client.buildSetupPasskeyUrl(options),
|
|
1066
|
+
setupAddressUrl: (options) => client.buildSetupAddressUrl(options)
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1069
|
+
function useSessionStatus() {
|
|
1070
|
+
const { client, state } = useDouveryAuth();
|
|
1071
|
+
const isExpired = useSignal(client.isSessionExpired());
|
|
1072
|
+
const needsVerification = useSignal(client.needsEmailVerification());
|
|
1073
|
+
const isGuest = useSignal(client.isGuestAccount());
|
|
1074
|
+
useTask$(({ track }) => {
|
|
1075
|
+
track(() => state.value);
|
|
1076
|
+
isExpired.value = client.isSessionExpired();
|
|
1077
|
+
needsVerification.value = client.needsEmailVerification();
|
|
1078
|
+
isGuest.value = client.isGuestAccount();
|
|
1079
|
+
});
|
|
1080
|
+
return { isExpired, needsVerification, isGuest };
|
|
809
1081
|
}
|
|
810
1082
|
|
|
811
|
-
export { DouveryAuthClient, DouveryAuthContext, DouveryAuthProvider, createDouveryAuth, useAuthActions, useDouveryAuth, useIsAuthenticated, useUser };
|
|
1083
|
+
export { DouveryAuthClient, DouveryAuthContext, DouveryAuthProvider, createDouveryAuth, useAuthActions, useAuthUrls, useDouveryAuth, useIsAuthenticated, useSessionStatus, useUser };
|
|
812
1084
|
//# sourceMappingURL=index.js.map
|
|
813
1085
|
//# sourceMappingURL=index.js.map
|