@oxyhq/auth 1.1.4 → 1.2.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.
@@ -10,10 +10,9 @@ const sonner_1 = require("sonner");
10
10
  const core_1 = require("@oxyhq/core");
11
11
  const core_2 = require("@oxyhq/core");
12
12
  const debug = (0, core_2.createDebugLogger)('SessionSocket');
13
- function useSessionSocket({ userId, activeSessionId, currentDeviceId, refreshSessions, logout, clearSessionState, baseURL, onRemoteSignOut, onSessionRemoved }) {
13
+ function useSessionSocket({ userId, activeSessionId, currentDeviceId, refreshSessions, logout, clearSessionState, baseURL, getAccessToken, onRemoteSignOut, onSessionRemoved }) {
14
14
  const socketRef = (0, react_1.useRef)(null);
15
- const joinedRoomRef = (0, react_1.useRef)(null);
16
- // Store callbacks in refs to avoid re-joining when they change
15
+ // Store callbacks in refs to avoid reconnecting when they change
17
16
  const refreshSessionsRef = (0, react_1.useRef)(refreshSessions);
18
17
  const logoutRef = (0, react_1.useRef)(logout);
19
18
  const clearSessionStateRef = (0, react_1.useRef)(clearSessionState);
@@ -21,6 +20,7 @@ function useSessionSocket({ userId, activeSessionId, currentDeviceId, refreshSes
21
20
  const onSessionRemovedRef = (0, react_1.useRef)(onSessionRemoved);
22
21
  const activeSessionIdRef = (0, react_1.useRef)(activeSessionId);
23
22
  const currentDeviceIdRef = (0, react_1.useRef)(currentDeviceId);
23
+ const getAccessTokenRef = (0, react_1.useRef)(getAccessToken);
24
24
  // Update refs when callbacks change
25
25
  (0, react_1.useEffect)(() => {
26
26
  refreshSessionsRef.current = refreshSessions;
@@ -30,35 +30,32 @@ function useSessionSocket({ userId, activeSessionId, currentDeviceId, refreshSes
30
30
  onSessionRemovedRef.current = onSessionRemoved;
31
31
  activeSessionIdRef.current = activeSessionId;
32
32
  currentDeviceIdRef.current = currentDeviceId;
33
- }, [refreshSessions, logout, clearSessionState, onRemoteSignOut, onSessionRemoved, activeSessionId, currentDeviceId]);
33
+ getAccessTokenRef.current = getAccessToken;
34
+ }, [refreshSessions, logout, clearSessionState, onRemoteSignOut, onSessionRemoved, activeSessionId, currentDeviceId, getAccessToken]);
34
35
  (0, react_1.useEffect)(() => {
35
36
  if (!userId || !baseURL) {
36
37
  // Clean up if userId or baseURL becomes invalid
37
- if (socketRef.current && joinedRoomRef.current) {
38
- socketRef.current.emit('leave', { userId: joinedRoomRef.current });
39
- joinedRoomRef.current = null;
38
+ if (socketRef.current) {
39
+ socketRef.current.disconnect();
40
+ socketRef.current = null;
40
41
  }
41
42
  return;
42
43
  }
43
- const roomId = `user:${userId}`;
44
- // Only create socket if it doesn't exist
45
- if (!socketRef.current) {
46
- socketRef.current = (0, socket_io_client_1.default)(baseURL, {
47
- transports: ['websocket'],
48
- });
44
+ // Disconnect previous socket if switching users
45
+ if (socketRef.current) {
46
+ socketRef.current.disconnect();
47
+ socketRef.current = null;
49
48
  }
49
+ // Connect with auth token; use callback so reconnections get a fresh token
50
+ socketRef.current = (0, socket_io_client_1.default)(baseURL, {
51
+ transports: ['websocket'],
52
+ auth: (cb) => {
53
+ const token = getAccessTokenRef.current();
54
+ cb({ token: token ?? '' });
55
+ },
56
+ });
50
57
  const socket = socketRef.current;
51
- // Only join if we haven't already joined this room
52
- if (joinedRoomRef.current !== roomId) {
53
- // Leave previous room if switching users
54
- if (joinedRoomRef.current) {
55
- socket.emit('leave', { userId: joinedRoomRef.current });
56
- }
57
- socket.emit('join', { userId: roomId });
58
- joinedRoomRef.current = roomId;
59
- debug.log('Emitting join for room:', roomId);
60
- }
61
- // Set up event handlers (only once per socket instance)
58
+ // Server auto-joins the user to `user:<userId>` room on connection
62
59
  const handleConnect = () => {
63
60
  debug.log('Socket connected:', socket.id);
64
61
  };
@@ -205,11 +202,8 @@ function useSessionSocket({ userId, activeSessionId, currentDeviceId, refreshSes
205
202
  return () => {
206
203
  socket.off('connect', handleConnect);
207
204
  socket.off('session_update', handleSessionUpdate);
208
- // Only leave on unmount if we're still in this room
209
- if (joinedRoomRef.current === roomId) {
210
- socket.emit('leave', { userId: roomId });
211
- joinedRoomRef.current = null;
212
- }
205
+ socket.disconnect();
206
+ socketRef.current = null;
213
207
  };
214
208
  }, [userId, baseURL]); // Only depend on userId and baseURL - callbacks are in refs
215
209
  }
@@ -4,10 +4,9 @@ import { toast } from 'sonner';
4
4
  import { logger } from '@oxyhq/core';
5
5
  import { createDebugLogger } from '@oxyhq/core';
6
6
  const debug = createDebugLogger('SessionSocket');
7
- export function useSessionSocket({ userId, activeSessionId, currentDeviceId, refreshSessions, logout, clearSessionState, baseURL, onRemoteSignOut, onSessionRemoved }) {
7
+ export function useSessionSocket({ userId, activeSessionId, currentDeviceId, refreshSessions, logout, clearSessionState, baseURL, getAccessToken, onRemoteSignOut, onSessionRemoved }) {
8
8
  const socketRef = useRef(null);
9
- const joinedRoomRef = useRef(null);
10
- // Store callbacks in refs to avoid re-joining when they change
9
+ // Store callbacks in refs to avoid reconnecting when they change
11
10
  const refreshSessionsRef = useRef(refreshSessions);
12
11
  const logoutRef = useRef(logout);
13
12
  const clearSessionStateRef = useRef(clearSessionState);
@@ -15,6 +14,7 @@ export function useSessionSocket({ userId, activeSessionId, currentDeviceId, ref
15
14
  const onSessionRemovedRef = useRef(onSessionRemoved);
16
15
  const activeSessionIdRef = useRef(activeSessionId);
17
16
  const currentDeviceIdRef = useRef(currentDeviceId);
17
+ const getAccessTokenRef = useRef(getAccessToken);
18
18
  // Update refs when callbacks change
19
19
  useEffect(() => {
20
20
  refreshSessionsRef.current = refreshSessions;
@@ -24,35 +24,32 @@ export function useSessionSocket({ userId, activeSessionId, currentDeviceId, ref
24
24
  onSessionRemovedRef.current = onSessionRemoved;
25
25
  activeSessionIdRef.current = activeSessionId;
26
26
  currentDeviceIdRef.current = currentDeviceId;
27
- }, [refreshSessions, logout, clearSessionState, onRemoteSignOut, onSessionRemoved, activeSessionId, currentDeviceId]);
27
+ getAccessTokenRef.current = getAccessToken;
28
+ }, [refreshSessions, logout, clearSessionState, onRemoteSignOut, onSessionRemoved, activeSessionId, currentDeviceId, getAccessToken]);
28
29
  useEffect(() => {
29
30
  if (!userId || !baseURL) {
30
31
  // Clean up if userId or baseURL becomes invalid
31
- if (socketRef.current && joinedRoomRef.current) {
32
- socketRef.current.emit('leave', { userId: joinedRoomRef.current });
33
- joinedRoomRef.current = null;
32
+ if (socketRef.current) {
33
+ socketRef.current.disconnect();
34
+ socketRef.current = null;
34
35
  }
35
36
  return;
36
37
  }
37
- const roomId = `user:${userId}`;
38
- // Only create socket if it doesn't exist
39
- if (!socketRef.current) {
40
- socketRef.current = io(baseURL, {
41
- transports: ['websocket'],
42
- });
38
+ // Disconnect previous socket if switching users
39
+ if (socketRef.current) {
40
+ socketRef.current.disconnect();
41
+ socketRef.current = null;
43
42
  }
43
+ // Connect with auth token; use callback so reconnections get a fresh token
44
+ socketRef.current = io(baseURL, {
45
+ transports: ['websocket'],
46
+ auth: (cb) => {
47
+ const token = getAccessTokenRef.current();
48
+ cb({ token: token ?? '' });
49
+ },
50
+ });
44
51
  const socket = socketRef.current;
45
- // Only join if we haven't already joined this room
46
- if (joinedRoomRef.current !== roomId) {
47
- // Leave previous room if switching users
48
- if (joinedRoomRef.current) {
49
- socket.emit('leave', { userId: joinedRoomRef.current });
50
- }
51
- socket.emit('join', { userId: roomId });
52
- joinedRoomRef.current = roomId;
53
- debug.log('Emitting join for room:', roomId);
54
- }
55
- // Set up event handlers (only once per socket instance)
52
+ // Server auto-joins the user to `user:<userId>` room on connection
56
53
  const handleConnect = () => {
57
54
  debug.log('Socket connected:', socket.id);
58
55
  };
@@ -199,11 +196,8 @@ export function useSessionSocket({ userId, activeSessionId, currentDeviceId, ref
199
196
  return () => {
200
197
  socket.off('connect', handleConnect);
201
198
  socket.off('session_update', handleSessionUpdate);
202
- // Only leave on unmount if we're still in this room
203
- if (joinedRoomRef.current === roomId) {
204
- socket.emit('leave', { userId: roomId });
205
- joinedRoomRef.current = null;
206
- }
199
+ socket.disconnect();
200
+ socketRef.current = null;
207
201
  };
208
202
  }, [userId, baseURL]); // Only depend on userId and baseURL - callbacks are in refs
209
203
  }
@@ -6,8 +6,9 @@ interface UseSessionSocketProps {
6
6
  logout: () => Promise<void>;
7
7
  clearSessionState: () => Promise<void>;
8
8
  baseURL: string;
9
+ getAccessToken: () => string | null;
9
10
  onRemoteSignOut?: () => void;
10
11
  onSessionRemoved?: (sessionId: string) => void;
11
12
  }
12
- export declare function useSessionSocket({ userId, activeSessionId, currentDeviceId, refreshSessions, logout, clearSessionState, baseURL, onRemoteSignOut, onSessionRemoved }: UseSessionSocketProps): void;
13
+ export declare function useSessionSocket({ userId, activeSessionId, currentDeviceId, refreshSessions, logout, clearSessionState, baseURL, getAccessToken, onRemoteSignOut, onSessionRemoved }: UseSessionSocketProps): void;
13
14
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxyhq/auth",
3
- "version": "1.1.4",
3
+ "version": "1.2.0",
4
4
  "description": "OxyHQ Web Authentication SDK — headless auth with React hooks for Next.js, Vite, and web apps",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -14,15 +14,15 @@ interface UseSessionSocketProps {
14
14
  logout: () => Promise<void>;
15
15
  clearSessionState: () => Promise<void>;
16
16
  baseURL: string;
17
+ getAccessToken: () => string | null;
17
18
  onRemoteSignOut?: () => void;
18
19
  onSessionRemoved?: (sessionId: string) => void;
19
20
  }
20
21
 
21
- export function useSessionSocket({ userId, activeSessionId, currentDeviceId, refreshSessions, logout, clearSessionState, baseURL, onRemoteSignOut, onSessionRemoved }: UseSessionSocketProps) {
22
+ export function useSessionSocket({ userId, activeSessionId, currentDeviceId, refreshSessions, logout, clearSessionState, baseURL, getAccessToken, onRemoteSignOut, onSessionRemoved }: UseSessionSocketProps) {
22
23
  const socketRef = useRef<any>(null);
23
- const joinedRoomRef = useRef<string | null>(null);
24
-
25
- // Store callbacks in refs to avoid re-joining when they change
24
+
25
+ // Store callbacks in refs to avoid reconnecting when they change
26
26
  const refreshSessionsRef = useRef(refreshSessions);
27
27
  const logoutRef = useRef(logout);
28
28
  const clearSessionStateRef = useRef(clearSessionState);
@@ -30,6 +30,7 @@ export function useSessionSocket({ userId, activeSessionId, currentDeviceId, ref
30
30
  const onSessionRemovedRef = useRef(onSessionRemoved);
31
31
  const activeSessionIdRef = useRef(activeSessionId);
32
32
  const currentDeviceIdRef = useRef(currentDeviceId);
33
+ const getAccessTokenRef = useRef(getAccessToken);
33
34
 
34
35
  // Update refs when callbacks change
35
36
  useEffect(() => {
@@ -40,42 +41,36 @@ export function useSessionSocket({ userId, activeSessionId, currentDeviceId, ref
40
41
  onSessionRemovedRef.current = onSessionRemoved;
41
42
  activeSessionIdRef.current = activeSessionId;
42
43
  currentDeviceIdRef.current = currentDeviceId;
43
- }, [refreshSessions, logout, clearSessionState, onRemoteSignOut, onSessionRemoved, activeSessionId, currentDeviceId]);
44
+ getAccessTokenRef.current = getAccessToken;
45
+ }, [refreshSessions, logout, clearSessionState, onRemoteSignOut, onSessionRemoved, activeSessionId, currentDeviceId, getAccessToken]);
44
46
 
45
47
  useEffect(() => {
46
48
  if (!userId || !baseURL) {
47
49
  // Clean up if userId or baseURL becomes invalid
48
- if (socketRef.current && joinedRoomRef.current) {
49
- socketRef.current.emit('leave', { userId: joinedRoomRef.current });
50
- joinedRoomRef.current = null;
50
+ if (socketRef.current) {
51
+ socketRef.current.disconnect();
52
+ socketRef.current = null;
51
53
  }
52
54
  return;
53
55
  }
54
56
 
55
- const roomId = `user:${userId}`;
56
-
57
- // Only create socket if it doesn't exist
58
- if (!socketRef.current) {
59
- socketRef.current = io(baseURL, {
60
- transports: ['websocket'],
61
- });
57
+ // Disconnect previous socket if switching users
58
+ if (socketRef.current) {
59
+ socketRef.current.disconnect();
60
+ socketRef.current = null;
62
61
  }
63
- const socket = socketRef.current;
64
62
 
65
- // Only join if we haven't already joined this room
66
- if (joinedRoomRef.current !== roomId) {
67
- // Leave previous room if switching users
68
- if (joinedRoomRef.current) {
69
- socket.emit('leave', { userId: joinedRoomRef.current });
70
- }
71
-
72
- socket.emit('join', { userId: roomId });
73
- joinedRoomRef.current = roomId;
74
-
75
- debug.log('Emitting join for room:', roomId);
76
- }
63
+ // Connect with auth token; use callback so reconnections get a fresh token
64
+ socketRef.current = io(baseURL, {
65
+ transports: ['websocket'],
66
+ auth: (cb: (data: { token: string }) => void) => {
67
+ const token = getAccessTokenRef.current();
68
+ cb({ token: token ?? '' });
69
+ },
70
+ });
71
+ const socket = socketRef.current;
77
72
 
78
- // Set up event handlers (only once per socket instance)
73
+ // Server auto-joins the user to `user:<userId>` room on connection
79
74
  const handleConnect = () => {
80
75
  debug.log('Socket connected:', socket.id);
81
76
  };
@@ -222,12 +217,8 @@ export function useSessionSocket({ userId, activeSessionId, currentDeviceId, ref
222
217
  return () => {
223
218
  socket.off('connect', handleConnect);
224
219
  socket.off('session_update', handleSessionUpdate);
225
-
226
- // Only leave on unmount if we're still in this room
227
- if (joinedRoomRef.current === roomId) {
228
- socket.emit('leave', { userId: roomId });
229
- joinedRoomRef.current = null;
230
- }
220
+ socket.disconnect();
221
+ socketRef.current = null;
231
222
  };
232
223
  }, [userId, baseURL]); // Only depend on userId and baseURL - callbacks are in refs
233
224
  }