11import { useSelector } from "@xstate/react" ;
2- import { useCallback , useEffect } from "react" ;
2+ import { useCallback , useEffect , useRef } from "react" ;
33import type { ActorRefFrom } from "xstate" ;
44import { supabase } from "../config/supabase" ;
55import type { rampMachine } from "../machines/ramp.machine" ;
@@ -12,25 +12,39 @@ export function useAuthTokens(actorRef: ActorRefFrom<typeof rampMachine>) {
1212 userId : state . context . userId
1313 } ) ) ;
1414
15+ // Track if we've already restored the session to avoid running multiple times
16+ const hasRestoredSession = useRef ( false ) ;
17+
1518 // Check for tokens in URL on mount (magic link callback)
1619 useEffect ( ( ) => {
1720 const urlTokens = AuthService . handleUrlTokens ( ) ;
1821 if ( urlTokens ) {
19- supabase . auth . getSession ( ) . then ( ( { data } ) => {
20- if ( data . session ) {
21- const tokens = {
22- access_token : data . session . access_token ,
23- refresh_token : data . session . refresh_token ,
24- user_id : data . session . user . id
25- } ;
22+ // Use the URL tokens to set session with Supabase, then get full user details
23+ supabase . auth
24+ . setSession ( {
25+ access_token : urlTokens . accessToken ,
26+ refresh_token : urlTokens . refreshToken
27+ } )
28+ . then ( ( { data, error } ) => {
29+ if ( error ) {
30+ console . error ( "Failed to set session from URL tokens:" , error ) ;
31+ return ;
32+ }
33+
34+ if ( data . session ) {
35+ const tokens = {
36+ accessToken : data . session . access_token ,
37+ refreshToken : data . session . refresh_token ,
38+ userId : data . session . user . id
39+ } ;
2640
27- AuthService . storeTokens ( tokens ) ;
28- actorRef . send ( { tokens, type : "AUTH_SUCCESS" } ) ;
41+ AuthService . storeTokens ( tokens ) ;
42+ actorRef . send ( { tokens, type : "AUTH_SUCCESS" } ) ;
2943
30- // Clean URL
31- window . history . replaceState ( { } , "" , window . location . pathname ) ;
32- }
33- } ) ;
44+ // Clean URL
45+ window . history . replaceState ( { } , "" , window . location . pathname ) ;
46+ }
47+ } ) ;
3448 }
3549 } , [ actorRef ] ) ;
3650
@@ -42,16 +56,20 @@ export function useAuthTokens(actorRef: ActorRefFrom<typeof rampMachine>) {
4256
4357 // Restore session from localStorage on mount
4458 useEffect ( ( ) => {
45- const tokens = AuthService . getTokens ( ) ;
46- if ( tokens && ! isAuthenticated ) {
47- actorRef . send ( {
48- tokens : {
49- access_token : tokens . access_token ,
50- refresh_token : tokens . refresh_token ,
51- user_id : tokens . user_id
52- } ,
53- type : "AUTH_SUCCESS"
54- } ) ;
59+ // Only restore once on initial mount to avoid infinite loops
60+ if ( ! hasRestoredSession . current && ! isAuthenticated ) {
61+ const tokens = AuthService . getTokens ( ) ;
62+ if ( tokens ) {
63+ hasRestoredSession . current = true ;
64+ actorRef . send ( {
65+ tokens : {
66+ accessToken : tokens . accessToken ,
67+ refreshToken : tokens . refreshToken ,
68+ userId : tokens . userId
69+ } ,
70+ type : "AUTH_SUCCESS"
71+ } ) ;
72+ }
5573 }
5674 } , [ actorRef , isAuthenticated ] ) ;
5775
0 commit comments