Ver código fonte

fix(dashboard): Re-sync channel token when activeChannelId persists but token is cleared (#4094)

Closes #4095
niko91i 1 semana atrás
pai
commit
2f3ff85d46

+ 32 - 7
packages/dashboard/src/lib/providers/channel-provider.tsx

@@ -96,6 +96,19 @@ export interface ChannelContext {
     refreshChannels: () => void;
 }
 
+/**
+ * Retrieves the channel token from localStorage.
+ * Returns null if localStorage is unavailable or an error occurs.
+ */
+function getChannelTokenFromLocalStorage(): string | null {
+    try {
+        return localStorage.getItem(LS_KEY_SELECTED_CHANNEL_TOKEN);
+    } catch (e) {
+        console.error('Failed to retrieve channel token from localStorage', e);
+        return null;
+    }
+}
+
 /**
  * Sets the channel token in localStorage, which is then used by the `api`
  * object to ensure we add the correct token header to all API calls.
@@ -183,27 +196,39 @@ export function ChannelProvider({ children }: Readonly<{ children: React.ReactNo
         // If selected channel is not valid for this user, reset it
         if (selectedChannelId && validChannelIds.length && !validChannelIds.includes(selectedChannelId)) {
             setSelectedChannelId(undefined);
-        }
-
-        // If no selected channel is set, use the first available channel
-        if (!selectedChannelId && channels.length > 0) {
+        } else if (selectedChannelId && channels.length > 0) {
+            // Ensure channel token in localStorage stays in sync with selected channel.
+            // This handles the case where activeChannelId persists but the token was cleared (e.g., after logout).
+            const selectedChannel = channels.find(c => c.id === selectedChannelId);
+            if (selectedChannel) {
+                const currentToken = getChannelTokenFromLocalStorage();
+                if (currentToken !== selectedChannel.token) {
+                    setChannelTokenInLocalStorage(selectedChannel.token);
+                    // Invalidate queries to refetch with the corrected token
+                    queryClient.invalidateQueries({
+                        queryKey: ['activeChannel', isAuthenticated],
+                    });
+                }
+            }
+        } else if (channels.length > 0) {
+            // If no selected channel is set, use the first available channel
             const defaultChannel = channels[0];
             setSelectedChannelId(defaultChannel.id);
             setChannelTokenInLocalStorage(defaultChannel.token);
         }
-    }, [selectedChannelId, channels]);
+    }, [selectedChannelId, channels, queryClient, isAuthenticated]);
 
     const isLoading = isActiveChannelLoading;
 
     // Find the selected channel from the list of channels
     const selectedChannel = activeChannelData?.activeChannel;
 
-    const refreshChannels = () => {
+    const refreshChannels = React.useCallback(() => {
         refreshCurrentUser();
         queryClient.invalidateQueries({
             queryKey: ['channels', isAuthenticated],
         });
-    };
+    }, [refreshCurrentUser, queryClient, isAuthenticated]);
 
     const contextValue: ChannelContext = React.useMemo(
         () => ({