@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/react/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, {
|
|
@@ -783,34 +970,40 @@ function DouveryAuthProvider({
|
|
|
783
970
|
});
|
|
784
971
|
return unsubscribe;
|
|
785
972
|
}, [client, onAuthenticated, onLogout, onError]);
|
|
786
|
-
const login = useCallback(
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
973
|
+
const login = useCallback(
|
|
974
|
+
async (options) => {
|
|
975
|
+
setIsLoading(true);
|
|
976
|
+
setError(null);
|
|
977
|
+
try {
|
|
978
|
+
await client.login(options);
|
|
979
|
+
} catch (err) {
|
|
980
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
981
|
+
setError(e);
|
|
982
|
+
onError?.(e);
|
|
983
|
+
throw e;
|
|
984
|
+
} finally {
|
|
985
|
+
setIsLoading(false);
|
|
986
|
+
}
|
|
987
|
+
},
|
|
988
|
+
[client, onError]
|
|
989
|
+
);
|
|
990
|
+
const logout = useCallback(
|
|
991
|
+
async (options) => {
|
|
992
|
+
setIsLoading(true);
|
|
993
|
+
setError(null);
|
|
994
|
+
try {
|
|
995
|
+
await client.logout(options);
|
|
996
|
+
} catch (err) {
|
|
997
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
998
|
+
setError(e);
|
|
999
|
+
onError?.(e);
|
|
1000
|
+
throw e;
|
|
1001
|
+
} finally {
|
|
1002
|
+
setIsLoading(false);
|
|
1003
|
+
}
|
|
1004
|
+
},
|
|
1005
|
+
[client, onError]
|
|
1006
|
+
);
|
|
814
1007
|
const getAccessToken = useCallback(() => client.getAccessToken(), [client]);
|
|
815
1008
|
const refreshTokens = useCallback(async () => {
|
|
816
1009
|
setIsLoading(true);
|
|
@@ -825,20 +1018,100 @@ function DouveryAuthProvider({
|
|
|
825
1018
|
setIsLoading(false);
|
|
826
1019
|
}
|
|
827
1020
|
}, [client, onError]);
|
|
828
|
-
const
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
1021
|
+
const selectAccount = useCallback(
|
|
1022
|
+
(options) => client.selectAccount(options),
|
|
1023
|
+
[client]
|
|
1024
|
+
);
|
|
1025
|
+
const addAccount = useCallback(
|
|
1026
|
+
(options) => client.addAccount(options),
|
|
1027
|
+
[client]
|
|
1028
|
+
);
|
|
1029
|
+
const register = useCallback(
|
|
1030
|
+
(options) => client.register(options),
|
|
1031
|
+
[client]
|
|
1032
|
+
);
|
|
1033
|
+
const recoverAccount = useCallback(
|
|
1034
|
+
(options) => client.recoverAccount(options),
|
|
1035
|
+
[client]
|
|
1036
|
+
);
|
|
1037
|
+
const verifyAccount = useCallback(
|
|
1038
|
+
(options) => client.verifyAccount(options),
|
|
1039
|
+
[client]
|
|
1040
|
+
);
|
|
1041
|
+
const upgradeAccount = useCallback(
|
|
1042
|
+
(options) => client.upgradeAccount(options),
|
|
1043
|
+
[client]
|
|
1044
|
+
);
|
|
1045
|
+
const setupPasskey = useCallback(
|
|
1046
|
+
(options) => client.setupPasskey(options),
|
|
1047
|
+
[client]
|
|
1048
|
+
);
|
|
1049
|
+
const setupAddress = useCallback(
|
|
1050
|
+
(options) => client.setupAddress(options),
|
|
1051
|
+
[client]
|
|
1052
|
+
);
|
|
1053
|
+
const revokeToken = useCallback(
|
|
1054
|
+
async (options) => {
|
|
1055
|
+
setIsLoading(true);
|
|
1056
|
+
setError(null);
|
|
1057
|
+
try {
|
|
1058
|
+
await client.revokeToken(options);
|
|
1059
|
+
} catch (err) {
|
|
1060
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
1061
|
+
setError(e);
|
|
1062
|
+
onError?.(e);
|
|
1063
|
+
throw e;
|
|
1064
|
+
} finally {
|
|
1065
|
+
setIsLoading(false);
|
|
1066
|
+
}
|
|
1067
|
+
},
|
|
1068
|
+
[client, onError]
|
|
1069
|
+
);
|
|
1070
|
+
const value = useMemo(
|
|
1071
|
+
() => ({
|
|
1072
|
+
state,
|
|
1073
|
+
isInitialized,
|
|
1074
|
+
isLoading,
|
|
1075
|
+
user: state.user,
|
|
1076
|
+
isAuthenticated: state.status === "authenticated",
|
|
1077
|
+
accessToken: state.tokens?.accessToken ?? null,
|
|
1078
|
+
error,
|
|
1079
|
+
login,
|
|
1080
|
+
logout,
|
|
1081
|
+
selectAccount,
|
|
1082
|
+
addAccount,
|
|
1083
|
+
register,
|
|
1084
|
+
recoverAccount,
|
|
1085
|
+
verifyAccount,
|
|
1086
|
+
upgradeAccount,
|
|
1087
|
+
setupPasskey,
|
|
1088
|
+
setupAddress,
|
|
1089
|
+
revokeToken,
|
|
1090
|
+
getAccessToken,
|
|
1091
|
+
refreshTokens,
|
|
1092
|
+
client
|
|
1093
|
+
}),
|
|
1094
|
+
[
|
|
1095
|
+
state,
|
|
1096
|
+
isInitialized,
|
|
1097
|
+
isLoading,
|
|
1098
|
+
error,
|
|
1099
|
+
login,
|
|
1100
|
+
logout,
|
|
1101
|
+
selectAccount,
|
|
1102
|
+
addAccount,
|
|
1103
|
+
register,
|
|
1104
|
+
recoverAccount,
|
|
1105
|
+
verifyAccount,
|
|
1106
|
+
upgradeAccount,
|
|
1107
|
+
setupPasskey,
|
|
1108
|
+
setupAddress,
|
|
1109
|
+
revokeToken,
|
|
1110
|
+
getAccessToken,
|
|
1111
|
+
refreshTokens,
|
|
1112
|
+
client
|
|
1113
|
+
]
|
|
1114
|
+
);
|
|
842
1115
|
return /* @__PURE__ */ jsx(DouveryAuthContext.Provider, { value, children });
|
|
843
1116
|
}
|
|
844
1117
|
function useDouveryAuth() {
|
|
@@ -859,10 +1132,65 @@ function useAccessToken() {
|
|
|
859
1132
|
return { accessToken, getAccessToken };
|
|
860
1133
|
}
|
|
861
1134
|
function useAuthActions() {
|
|
862
|
-
const {
|
|
863
|
-
|
|
1135
|
+
const {
|
|
1136
|
+
login,
|
|
1137
|
+
logout,
|
|
1138
|
+
selectAccount,
|
|
1139
|
+
addAccount,
|
|
1140
|
+
register,
|
|
1141
|
+
recoverAccount,
|
|
1142
|
+
verifyAccount,
|
|
1143
|
+
upgradeAccount,
|
|
1144
|
+
setupPasskey,
|
|
1145
|
+
setupAddress,
|
|
1146
|
+
revokeToken,
|
|
1147
|
+
isLoading
|
|
1148
|
+
} = useDouveryAuth();
|
|
1149
|
+
return {
|
|
1150
|
+
login,
|
|
1151
|
+
logout,
|
|
1152
|
+
selectAccount,
|
|
1153
|
+
addAccount,
|
|
1154
|
+
register,
|
|
1155
|
+
recoverAccount,
|
|
1156
|
+
verifyAccount,
|
|
1157
|
+
upgradeAccount,
|
|
1158
|
+
setupPasskey,
|
|
1159
|
+
setupAddress,
|
|
1160
|
+
revokeToken,
|
|
1161
|
+
isLoading
|
|
1162
|
+
};
|
|
1163
|
+
}
|
|
1164
|
+
function useAuthUrls() {
|
|
1165
|
+
const { client } = useDouveryAuth();
|
|
1166
|
+
return useMemo(
|
|
1167
|
+
() => ({
|
|
1168
|
+
loginUrl: (options) => client.buildLoginUrl(options),
|
|
1169
|
+
logoutUrl: (options) => client.buildLogoutUrl(options),
|
|
1170
|
+
selectAccountUrl: (options) => client.buildSelectAccountUrl(options),
|
|
1171
|
+
addAccountUrl: (options) => client.buildAddAccountUrl(options),
|
|
1172
|
+
registerUrl: (options) => client.buildRegisterUrl(options),
|
|
1173
|
+
recoverAccountUrl: (options) => client.buildRecoverAccountUrl(options),
|
|
1174
|
+
verifyAccountUrl: (options) => client.buildVerifyAccountUrl(options),
|
|
1175
|
+
upgradeAccountUrl: (options) => client.buildUpgradeAccountUrl(options),
|
|
1176
|
+
setupPasskeyUrl: (options) => client.buildSetupPasskeyUrl(options),
|
|
1177
|
+
setupAddressUrl: (options) => client.buildSetupAddressUrl(options)
|
|
1178
|
+
}),
|
|
1179
|
+
[client]
|
|
1180
|
+
);
|
|
1181
|
+
}
|
|
1182
|
+
function useSessionStatus() {
|
|
1183
|
+
const { client, state } = useDouveryAuth();
|
|
1184
|
+
return useMemo(
|
|
1185
|
+
() => ({
|
|
1186
|
+
isExpired: client.isSessionExpired(),
|
|
1187
|
+
needsVerification: client.needsEmailVerification(),
|
|
1188
|
+
isGuest: client.isGuestAccount()
|
|
1189
|
+
}),
|
|
1190
|
+
[client, state]
|
|
1191
|
+
);
|
|
864
1192
|
}
|
|
865
1193
|
|
|
866
|
-
export { DouveryAuthClient, DouveryAuthProvider, createDouveryAuth, useAccessToken, useAuthActions, useDouveryAuth, useIsAuthenticated, useUser };
|
|
1194
|
+
export { DouveryAuthClient, DouveryAuthProvider, createDouveryAuth, useAccessToken, useAuthActions, useAuthUrls, useDouveryAuth, useIsAuthenticated, useSessionStatus, useUser };
|
|
867
1195
|
//# sourceMappingURL=index.js.map
|
|
868
1196
|
//# sourceMappingURL=index.js.map
|