@oxyhq/auth 1.0.0 → 1.1.1
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/cjs/WebOxyProvider.js +19 -20
- package/dist/cjs/hooks/useWebSSO.js +3 -3
- package/dist/cjs/utils/storageHelpers.js +3 -1
- package/dist/esm/WebOxyProvider.js +19 -20
- package/dist/esm/hooks/useWebSSO.js +3 -3
- package/dist/esm/utils/storageHelpers.js +3 -1
- package/package.json +1 -1
- package/src/WebOxyProvider.tsx +22 -19
- package/src/hooks/useWebSSO.ts +3 -3
- package/src/utils/storageHelpers.ts +3 -1
|
@@ -45,30 +45,21 @@ function WebOxyProvider({ children, baseURL, authWebUrl, onAuthStateChange, onEr
|
|
|
45
45
|
const [isLoading, setIsLoading] = (0, react_1.useState)(!skipAutoCheck);
|
|
46
46
|
const [error, setError] = (0, react_1.useState)(null);
|
|
47
47
|
const [activeSessionId, setActiveSessionId] = (0, react_1.useState)(null);
|
|
48
|
-
|
|
48
|
+
// Sessions array kept as constant empty for API compatibility.
|
|
49
|
+
// Multi-session management is handled by @oxyhq/services (OxyContext) for RN apps.
|
|
50
|
+
const sessions = [];
|
|
49
51
|
const isAuthenticated = !!user;
|
|
50
52
|
const handleAuthSuccess = (0, react_1.useCallback)(async (session, method = 'credentials') => {
|
|
51
53
|
await authManager.handleAuthSuccess(session, method);
|
|
52
|
-
// Set active session
|
|
53
54
|
if (session.sessionId) {
|
|
54
55
|
setActiveSessionId(session.sessionId);
|
|
55
56
|
}
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (fullUser) {
|
|
60
|
-
setUser(fullUser);
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
setUser(session.user);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
catch {
|
|
67
|
-
setUser(session.user);
|
|
68
|
-
}
|
|
57
|
+
// Use the session user directly to avoid an extra API round-trip.
|
|
58
|
+
// The session already contains user data from the auth exchange.
|
|
59
|
+
setUser(session.user);
|
|
69
60
|
setError(null);
|
|
70
61
|
setIsLoading(false);
|
|
71
|
-
}, [authManager
|
|
62
|
+
}, [authManager]);
|
|
72
63
|
const handleAuthError = (0, react_1.useCallback)((err) => {
|
|
73
64
|
const errorMessage = err instanceof Error ? err.message : 'Authentication failed';
|
|
74
65
|
setError(errorMessage);
|
|
@@ -119,8 +110,18 @@ function WebOxyProvider({ children, baseURL, authWebUrl, onAuthStateChange, onEr
|
|
|
119
110
|
setIsLoading(false);
|
|
120
111
|
}
|
|
121
112
|
};
|
|
122
|
-
|
|
123
|
-
|
|
113
|
+
// Safety timeout: if all auth methods stall, stop loading
|
|
114
|
+
const INIT_TIMEOUT_MS = 15000;
|
|
115
|
+
const timeoutId = setTimeout(() => {
|
|
116
|
+
if (mounted) {
|
|
117
|
+
setIsLoading(false);
|
|
118
|
+
}
|
|
119
|
+
}, INIT_TIMEOUT_MS);
|
|
120
|
+
initAuth().finally(() => clearTimeout(timeoutId));
|
|
121
|
+
return () => {
|
|
122
|
+
mounted = false;
|
|
123
|
+
clearTimeout(timeoutId);
|
|
124
|
+
};
|
|
124
125
|
}, [oxyServices, crossDomainAuth, authManager, skipAutoCheck, handleAuthSuccess]);
|
|
125
126
|
(0, react_1.useEffect)(() => {
|
|
126
127
|
onAuthStateChange?.(user);
|
|
@@ -184,7 +185,6 @@ function WebOxyProvider({ children, baseURL, authWebUrl, onAuthStateChange, onEr
|
|
|
184
185
|
await authManager.signOut();
|
|
185
186
|
setUser(null);
|
|
186
187
|
setActiveSessionId(null);
|
|
187
|
-
setSessions([]);
|
|
188
188
|
}
|
|
189
189
|
catch (err) {
|
|
190
190
|
const errorMessage = err instanceof Error ? err.message : 'Sign out failed';
|
|
@@ -210,7 +210,6 @@ function WebOxyProvider({ children, baseURL, authWebUrl, onAuthStateChange, onEr
|
|
|
210
210
|
await authManager.signOut();
|
|
211
211
|
setUser(null);
|
|
212
212
|
setActiveSessionId(null);
|
|
213
|
-
setSessions([]);
|
|
214
213
|
}, [authManager]);
|
|
215
214
|
(0, react_1.useEffect)(() => {
|
|
216
215
|
return () => { authManager.destroy(); };
|
|
@@ -57,7 +57,7 @@ function useWebSSO({ oxyServices, onSessionFound, onSSOUnavailable, onError, ena
|
|
|
57
57
|
const isCheckingRef = (0, react_1.useRef)(false);
|
|
58
58
|
const hasCheckedRef = (0, react_1.useRef)(false);
|
|
59
59
|
// Check FedCM support once
|
|
60
|
-
const fedCMSupported = isWebBrowser() && oxyServices.isFedCMSupported
|
|
60
|
+
const fedCMSupported = isWebBrowser() && oxyServices.isFedCMSupported();
|
|
61
61
|
const checkSSO = (0, react_1.useCallback)(async () => {
|
|
62
62
|
if (!isWebBrowser() || isCheckingRef.current) {
|
|
63
63
|
return null;
|
|
@@ -74,7 +74,7 @@ function useWebSSO({ oxyServices, onSessionFound, onSSOUnavailable, onError, ena
|
|
|
74
74
|
}
|
|
75
75
|
isCheckingRef.current = true;
|
|
76
76
|
try {
|
|
77
|
-
const session = await oxyServices.silentSignInWithFedCM
|
|
77
|
+
const session = await oxyServices.silentSignInWithFedCM();
|
|
78
78
|
if (session) {
|
|
79
79
|
await onSessionFound(session);
|
|
80
80
|
return session;
|
|
@@ -106,7 +106,7 @@ function useWebSSO({ oxyServices, onSessionFound, onSSOUnavailable, onError, ena
|
|
|
106
106
|
}
|
|
107
107
|
isCheckingRef.current = true;
|
|
108
108
|
try {
|
|
109
|
-
const session = await oxyServices.signInWithFedCM
|
|
109
|
+
const session = await oxyServices.signInWithFedCM();
|
|
110
110
|
if (session) {
|
|
111
111
|
await onSessionFound(session);
|
|
112
112
|
return session;
|
|
@@ -106,7 +106,9 @@ const createNativeStorage = async () => {
|
|
|
106
106
|
return asyncStorageInstance;
|
|
107
107
|
}
|
|
108
108
|
try {
|
|
109
|
-
|
|
109
|
+
// Variable indirection prevents bundlers (Vite, webpack) from statically resolving this
|
|
110
|
+
const moduleName = '@react-native-async-storage/async-storage';
|
|
111
|
+
const asyncStorageModule = await Promise.resolve(`${moduleName}`).then(s => __importStar(require(s)));
|
|
110
112
|
asyncStorageInstance = asyncStorageModule.default;
|
|
111
113
|
return asyncStorageInstance;
|
|
112
114
|
}
|
|
@@ -40,30 +40,21 @@ export function WebOxyProvider({ children, baseURL, authWebUrl, onAuthStateChang
|
|
|
40
40
|
const [isLoading, setIsLoading] = useState(!skipAutoCheck);
|
|
41
41
|
const [error, setError] = useState(null);
|
|
42
42
|
const [activeSessionId, setActiveSessionId] = useState(null);
|
|
43
|
-
|
|
43
|
+
// Sessions array kept as constant empty for API compatibility.
|
|
44
|
+
// Multi-session management is handled by @oxyhq/services (OxyContext) for RN apps.
|
|
45
|
+
const sessions = [];
|
|
44
46
|
const isAuthenticated = !!user;
|
|
45
47
|
const handleAuthSuccess = useCallback(async (session, method = 'credentials') => {
|
|
46
48
|
await authManager.handleAuthSuccess(session, method);
|
|
47
|
-
// Set active session
|
|
48
49
|
if (session.sessionId) {
|
|
49
50
|
setActiveSessionId(session.sessionId);
|
|
50
51
|
}
|
|
51
|
-
//
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (fullUser) {
|
|
55
|
-
setUser(fullUser);
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
setUser(session.user);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
catch {
|
|
62
|
-
setUser(session.user);
|
|
63
|
-
}
|
|
52
|
+
// Use the session user directly to avoid an extra API round-trip.
|
|
53
|
+
// The session already contains user data from the auth exchange.
|
|
54
|
+
setUser(session.user);
|
|
64
55
|
setError(null);
|
|
65
56
|
setIsLoading(false);
|
|
66
|
-
}, [authManager
|
|
57
|
+
}, [authManager]);
|
|
67
58
|
const handleAuthError = useCallback((err) => {
|
|
68
59
|
const errorMessage = err instanceof Error ? err.message : 'Authentication failed';
|
|
69
60
|
setError(errorMessage);
|
|
@@ -114,8 +105,18 @@ export function WebOxyProvider({ children, baseURL, authWebUrl, onAuthStateChang
|
|
|
114
105
|
setIsLoading(false);
|
|
115
106
|
}
|
|
116
107
|
};
|
|
117
|
-
|
|
118
|
-
|
|
108
|
+
// Safety timeout: if all auth methods stall, stop loading
|
|
109
|
+
const INIT_TIMEOUT_MS = 15000;
|
|
110
|
+
const timeoutId = setTimeout(() => {
|
|
111
|
+
if (mounted) {
|
|
112
|
+
setIsLoading(false);
|
|
113
|
+
}
|
|
114
|
+
}, INIT_TIMEOUT_MS);
|
|
115
|
+
initAuth().finally(() => clearTimeout(timeoutId));
|
|
116
|
+
return () => {
|
|
117
|
+
mounted = false;
|
|
118
|
+
clearTimeout(timeoutId);
|
|
119
|
+
};
|
|
119
120
|
}, [oxyServices, crossDomainAuth, authManager, skipAutoCheck, handleAuthSuccess]);
|
|
120
121
|
useEffect(() => {
|
|
121
122
|
onAuthStateChange?.(user);
|
|
@@ -179,7 +180,6 @@ export function WebOxyProvider({ children, baseURL, authWebUrl, onAuthStateChang
|
|
|
179
180
|
await authManager.signOut();
|
|
180
181
|
setUser(null);
|
|
181
182
|
setActiveSessionId(null);
|
|
182
|
-
setSessions([]);
|
|
183
183
|
}
|
|
184
184
|
catch (err) {
|
|
185
185
|
const errorMessage = err instanceof Error ? err.message : 'Sign out failed';
|
|
@@ -205,7 +205,6 @@ export function WebOxyProvider({ children, baseURL, authWebUrl, onAuthStateChang
|
|
|
205
205
|
await authManager.signOut();
|
|
206
206
|
setUser(null);
|
|
207
207
|
setActiveSessionId(null);
|
|
208
|
-
setSessions([]);
|
|
209
208
|
}, [authManager]);
|
|
210
209
|
useEffect(() => {
|
|
211
210
|
return () => { authManager.destroy(); };
|
|
@@ -53,7 +53,7 @@ export function useWebSSO({ oxyServices, onSessionFound, onSSOUnavailable, onErr
|
|
|
53
53
|
const isCheckingRef = useRef(false);
|
|
54
54
|
const hasCheckedRef = useRef(false);
|
|
55
55
|
// Check FedCM support once
|
|
56
|
-
const fedCMSupported = isWebBrowser() && oxyServices.isFedCMSupported
|
|
56
|
+
const fedCMSupported = isWebBrowser() && oxyServices.isFedCMSupported();
|
|
57
57
|
const checkSSO = useCallback(async () => {
|
|
58
58
|
if (!isWebBrowser() || isCheckingRef.current) {
|
|
59
59
|
return null;
|
|
@@ -70,7 +70,7 @@ export function useWebSSO({ oxyServices, onSessionFound, onSSOUnavailable, onErr
|
|
|
70
70
|
}
|
|
71
71
|
isCheckingRef.current = true;
|
|
72
72
|
try {
|
|
73
|
-
const session = await oxyServices.silentSignInWithFedCM
|
|
73
|
+
const session = await oxyServices.silentSignInWithFedCM();
|
|
74
74
|
if (session) {
|
|
75
75
|
await onSessionFound(session);
|
|
76
76
|
return session;
|
|
@@ -102,7 +102,7 @@ export function useWebSSO({ oxyServices, onSessionFound, onSSOUnavailable, onErr
|
|
|
102
102
|
}
|
|
103
103
|
isCheckingRef.current = true;
|
|
104
104
|
try {
|
|
105
|
-
const session = await oxyServices.signInWithFedCM
|
|
105
|
+
const session = await oxyServices.signInWithFedCM();
|
|
106
106
|
if (session) {
|
|
107
107
|
await onSessionFound(session);
|
|
108
108
|
return session;
|
|
@@ -70,7 +70,9 @@ const createNativeStorage = async () => {
|
|
|
70
70
|
return asyncStorageInstance;
|
|
71
71
|
}
|
|
72
72
|
try {
|
|
73
|
-
|
|
73
|
+
// Variable indirection prevents bundlers (Vite, webpack) from statically resolving this
|
|
74
|
+
const moduleName = '@react-native-async-storage/async-storage';
|
|
75
|
+
const asyncStorageModule = await import(moduleName);
|
|
74
76
|
asyncStorageInstance = asyncStorageModule.default;
|
|
75
77
|
return asyncStorageInstance;
|
|
76
78
|
}
|
package/package.json
CHANGED
package/src/WebOxyProvider.tsx
CHANGED
|
@@ -105,7 +105,10 @@ export function WebOxyProvider({
|
|
|
105
105
|
const [isLoading, setIsLoading] = useState(!skipAutoCheck);
|
|
106
106
|
const [error, setError] = useState<string | null>(null);
|
|
107
107
|
const [activeSessionId, setActiveSessionId] = useState<string | null>(null);
|
|
108
|
-
|
|
108
|
+
|
|
109
|
+
// Sessions array kept as constant empty for API compatibility.
|
|
110
|
+
// Multi-session management is handled by @oxyhq/services (OxyContext) for RN apps.
|
|
111
|
+
const sessions: ClientSession[] = [];
|
|
109
112
|
|
|
110
113
|
const isAuthenticated = !!user;
|
|
111
114
|
|
|
@@ -115,26 +118,16 @@ export function WebOxyProvider({
|
|
|
115
118
|
) => {
|
|
116
119
|
await authManager.handleAuthSuccess(session, method);
|
|
117
120
|
|
|
118
|
-
// Set active session
|
|
119
121
|
if (session.sessionId) {
|
|
120
122
|
setActiveSessionId(session.sessionId);
|
|
121
123
|
}
|
|
122
124
|
|
|
123
|
-
//
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (fullUser) {
|
|
127
|
-
setUser(fullUser);
|
|
128
|
-
} else {
|
|
129
|
-
setUser(session.user as User);
|
|
130
|
-
}
|
|
131
|
-
} catch {
|
|
132
|
-
setUser(session.user as User);
|
|
133
|
-
}
|
|
134
|
-
|
|
125
|
+
// Use the session user directly to avoid an extra API round-trip.
|
|
126
|
+
// The session already contains user data from the auth exchange.
|
|
127
|
+
setUser(session.user as User);
|
|
135
128
|
setError(null);
|
|
136
129
|
setIsLoading(false);
|
|
137
|
-
}, [authManager
|
|
130
|
+
}, [authManager]);
|
|
138
131
|
|
|
139
132
|
const handleAuthError = useCallback((err: unknown) => {
|
|
140
133
|
const errorMessage = err instanceof Error ? err.message : 'Authentication failed';
|
|
@@ -187,8 +180,20 @@ export function WebOxyProvider({
|
|
|
187
180
|
}
|
|
188
181
|
};
|
|
189
182
|
|
|
190
|
-
|
|
191
|
-
|
|
183
|
+
// Safety timeout: if all auth methods stall, stop loading
|
|
184
|
+
const INIT_TIMEOUT_MS = 15_000;
|
|
185
|
+
const timeoutId = setTimeout(() => {
|
|
186
|
+
if (mounted) {
|
|
187
|
+
setIsLoading(false);
|
|
188
|
+
}
|
|
189
|
+
}, INIT_TIMEOUT_MS);
|
|
190
|
+
|
|
191
|
+
initAuth().finally(() => clearTimeout(timeoutId));
|
|
192
|
+
|
|
193
|
+
return () => {
|
|
194
|
+
mounted = false;
|
|
195
|
+
clearTimeout(timeoutId);
|
|
196
|
+
};
|
|
192
197
|
}, [oxyServices, crossDomainAuth, authManager, skipAutoCheck, handleAuthSuccess]);
|
|
193
198
|
|
|
194
199
|
useEffect(() => {
|
|
@@ -258,7 +263,6 @@ export function WebOxyProvider({
|
|
|
258
263
|
await authManager.signOut();
|
|
259
264
|
setUser(null);
|
|
260
265
|
setActiveSessionId(null);
|
|
261
|
-
setSessions([]);
|
|
262
266
|
} catch (err) {
|
|
263
267
|
const errorMessage = err instanceof Error ? err.message : 'Sign out failed';
|
|
264
268
|
setError(errorMessage);
|
|
@@ -283,7 +287,6 @@ export function WebOxyProvider({
|
|
|
283
287
|
await authManager.signOut();
|
|
284
288
|
setUser(null);
|
|
285
289
|
setActiveSessionId(null);
|
|
286
|
-
setSessions([]);
|
|
287
290
|
}, [authManager]);
|
|
288
291
|
|
|
289
292
|
useEffect(() => {
|
package/src/hooks/useWebSSO.ts
CHANGED
|
@@ -84,7 +84,7 @@ export function useWebSSO({
|
|
|
84
84
|
const hasCheckedRef = useRef(false);
|
|
85
85
|
|
|
86
86
|
// Check FedCM support once
|
|
87
|
-
const fedCMSupported = isWebBrowser() &&
|
|
87
|
+
const fedCMSupported = isWebBrowser() && oxyServices.isFedCMSupported();
|
|
88
88
|
|
|
89
89
|
const checkSSO = useCallback(async (): Promise<SessionLoginResponse | null> => {
|
|
90
90
|
if (!isWebBrowser() || isCheckingRef.current) {
|
|
@@ -106,7 +106,7 @@ export function useWebSSO({
|
|
|
106
106
|
isCheckingRef.current = true;
|
|
107
107
|
|
|
108
108
|
try {
|
|
109
|
-
const session = await
|
|
109
|
+
const session = await oxyServices.silentSignInWithFedCM();
|
|
110
110
|
|
|
111
111
|
if (session) {
|
|
112
112
|
await onSessionFound(session);
|
|
@@ -142,7 +142,7 @@ export function useWebSSO({
|
|
|
142
142
|
isCheckingRef.current = true;
|
|
143
143
|
|
|
144
144
|
try {
|
|
145
|
-
const session = await
|
|
145
|
+
const session = await oxyServices.signInWithFedCM();
|
|
146
146
|
|
|
147
147
|
if (session) {
|
|
148
148
|
await onSessionFound(session);
|
|
@@ -85,7 +85,9 @@ const createNativeStorage = async (): Promise<StorageInterface> => {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
try {
|
|
88
|
-
|
|
88
|
+
// Variable indirection prevents bundlers (Vite, webpack) from statically resolving this
|
|
89
|
+
const moduleName = '@react-native-async-storage/async-storage';
|
|
90
|
+
const asyncStorageModule = await import(moduleName);
|
|
89
91
|
asyncStorageInstance = asyncStorageModule.default as unknown as StorageInterface;
|
|
90
92
|
return asyncStorageInstance;
|
|
91
93
|
} catch (error) {
|