@@ -3957,24 +3957,65 @@ export async function registerDeviceSession(
39573957
39583958/**
39593959 * Sync all sessions for a user to use the correct org_id
3960- * Call this after org is loaded to fix sessions that were created with null org_id
3960+ * Call this after org is loaded to fix sessions that were created with null or wrong org_id
39613961 */
39623962export async function syncUserSessionsOrgId ( userId : string , orgId : string ) : Promise < void > {
39633963 const client = getSupabaseClient ( )
39643964
39653965 console . log ( '[Session] Syncing all user sessions to org_id:' , orgId ?. substring ( 0 , 8 ) + '...' )
39663966
3967- // Update all active sessions for this user to have the correct org_id
3968- const { error } = await client
3967+ // Update ALL active sessions for this user to have the correct org_id
3968+ // Use unconditional update - simpler and ensures all sessions have correct org_id
3969+ // The update only affects this user's sessions, so it's safe
3970+ const { data, error } = await client
39693971 . from ( 'user_sessions' )
39703972 . update ( { org_id : orgId } )
39713973 . eq ( 'user_id' , userId )
3972- . is ( 'org_id' , null ) // Only update sessions with NULL org_id
3974+ . select ( 'id' )
39733975
39743976 if ( error ) {
39753977 console . error ( '[Session] Failed to sync session org_ids:' , error . message )
39763978 } else {
3977- console . log ( '[Session] Session org_ids synced successfully' )
3979+ console . log ( '[Session] Session org_ids synced successfully, updated:' , data ?. length || 0 , 'sessions' )
3980+ }
3981+ }
3982+
3983+ /**
3984+ * Ensure the current user has the correct org_id in the database
3985+ * This calls a database RPC that checks and fixes org_id based on email domain
3986+ * Should be called on every app boot to prevent org_id mismatch issues
3987+ */
3988+ export async function ensureUserOrgId ( ) : Promise < { success : boolean ; fixed : boolean ; org_id ?: string ; error ?: string } > {
3989+ const client = getSupabaseClient ( )
3990+
3991+ console . log ( '[Auth] Ensuring user org_id is correct...' )
3992+
3993+ try {
3994+ const { data, error } = await client . rpc ( 'ensure_user_org_id' as never )
3995+
3996+ if ( error ) {
3997+ // RPC might not exist yet (before migration runs)
3998+ console . warn ( '[Auth] ensure_user_org_id RPC failed (run migration if not done):' , error . message )
3999+ return { success : false , fixed : false , error : error . message }
4000+ }
4001+
4002+ const result = data as { success : boolean ; fixed : boolean ; org_id ?: string ; previous_org_id ?: string ; new_org_id ?: string ; error ?: string }
4003+
4004+ if ( result . fixed ) {
4005+ console . log ( '[Auth] Fixed user org_id:' , result . previous_org_id ?. substring ( 0 , 8 ) + '... ->' , result . new_org_id ?. substring ( 0 , 8 ) + '...' )
4006+ } else {
4007+ console . log ( '[Auth] User org_id is correct:' , result . org_id ?. substring ( 0 , 8 ) + '...' )
4008+ }
4009+
4010+ return {
4011+ success : result . success ,
4012+ fixed : result . fixed ,
4013+ org_id : result . new_org_id || result . org_id ,
4014+ error : result . error
4015+ }
4016+ } catch ( err ) {
4017+ console . error ( '[Auth] ensureUserOrgId failed:' , err )
4018+ return { success : false , fixed : false , error : String ( err ) }
39784019 }
39794020}
39804021
@@ -4232,24 +4273,29 @@ export async function getOrgOnlineUsers(orgId: string): Promise<{ users: OnlineU
42324273 // Get sessions active within the last 5 minutes
42334274 const fiveMinutesAgo = new Date ( Date . now ( ) - 5 * 60 * 1000 ) . toISOString ( )
42344275
4235- console . log ( '[OnlineUsers] Fetching online users for org:' , orgId , 'since:' , fiveMinutesAgo )
4276+ console . log ( '[OnlineUsers] Fetching online users for org:' , orgId ?. substring ( 0 , 8 ) + '...' , 'since:' , fiveMinutesAgo )
42364277
4237- // First, let's debug by fetching ALL active sessions for this org (without RLS filtering)
4278+ // First, let's debug by fetching ALL active sessions visible to current user (RLS applies)
4279+ // This helps diagnose if the RLS policy is working correctly
42384280 const { data : debugData , error : debugError } = await client
42394281 . from ( 'user_sessions' )
42404282 . select ( 'user_id, org_id, machine_name, is_active, last_seen' )
42414283 . eq ( 'is_active' , true )
42424284 . gte ( 'last_seen' , fiveMinutesAgo )
42434285
4244- console . log ( '[OnlineUsers] DEBUG - All active sessions visible to current user:' ,
4245- debugData ?. map ( s => ( {
4246- user_id : s . user_id ?. substring ( 0 , 8 ) ,
4247- org_id : s . org_id ?. substring ( 0 , 8 ) || 'NULL' ,
4248- machine : s . machine_name ,
4249- last_seen : s . last_seen
4250- } ) ) || [ ] ,
4251- 'Error:' , debugError ?. message || 'none'
4252- )
4286+ console . log ( '[OnlineUsers] DEBUG - All active sessions visible to current user (RLS filtered):' ,
4287+ debugData ?. length || 0 , 'sessions' )
4288+ if ( debugData && debugData . length > 0 ) {
4289+ debugData . forEach ( s => {
4290+ console . log ( '[OnlineUsers] -' , s . machine_name ,
4291+ '| user:' , s . user_id ?. substring ( 0 , 8 ) + '...' ,
4292+ '| org:' , s . org_id ?. substring ( 0 , 8 ) || 'NULL' ,
4293+ '| last_seen:' , new Date ( s . last_seen ) . toLocaleTimeString ( ) )
4294+ } )
4295+ }
4296+ if ( debugError ) {
4297+ console . error ( '[OnlineUsers] DEBUG query error:' , debugError . message )
4298+ }
42534299
42544300 const { data, error } = await client
42554301 . from ( 'user_sessions' )
@@ -4310,6 +4356,8 @@ export function subscribeToOrgOnlineUsers(
43104356) : ( ) => void {
43114357 const client = getSupabaseClient ( )
43124358
4359+ console . log ( '[OnlineUsers] Subscribing to realtime updates for org:' , orgId ?. substring ( 0 , 8 ) + '...' )
4360+
43134361 const channel = client
43144362 . channel ( `org_sessions:${ orgId } ` )
43154363 . on < UserSession > (
@@ -4320,15 +4368,22 @@ export function subscribeToOrgOnlineUsers(
43204368 table : 'user_sessions' ,
43214369 filter : `org_id=eq.${ orgId } `
43224370 } ,
4323- async ( ) => {
4371+ async ( payload ) => {
4372+ console . log ( '[OnlineUsers] Realtime event received:' , payload . eventType ,
4373+ '| user:' , ( payload . new as UserSession ) ?. user_id ?. substring ( 0 , 8 ) || ( payload . old as UserSession ) ?. user_id ?. substring ( 0 , 8 ) || 'unknown' )
4374+
43244375 // When any org session changes, fetch all online users
43254376 const { users } = await getOrgOnlineUsers ( orgId )
4377+ console . log ( '[OnlineUsers] Refreshed online users after realtime event:' , users . length )
43264378 onUsersChange ( users )
43274379 }
43284380 )
4329- . subscribe ( )
4381+ . subscribe ( ( status ) => {
4382+ console . log ( '[OnlineUsers] Subscription status:' , status )
4383+ } )
43304384
43314385 return ( ) => {
4386+ console . log ( '[OnlineUsers] Unsubscribing from realtime updates for org:' , orgId ?. substring ( 0 , 8 ) + '...' )
43324387 channel . unsubscribe ( )
43334388 }
43344389}
0 commit comments