Просмотр исходного кода

fix(dashboard): Fix several issues related to login/logout

Michael Bromley 8 месяцев назад
Родитель
Сommit
7b3b917366

+ 8 - 8
packages/dashboard/src/app/app-providers.tsx

@@ -14,15 +14,15 @@ export function AppProviders({ children }: { children: React.ReactNode }) {
     return (
         <I18nProvider>
             <QueryClientProvider client={queryClient}>
-                <ServerConfigProvider>
-                    <UserSettingsProvider>
-                        <ThemeProvider defaultTheme="system">
-                            <AuthProvider>
+                <UserSettingsProvider>
+                    <ThemeProvider defaultTheme="system">
+                        <AuthProvider>
+                            <ServerConfigProvider>
                                 <ChannelProvider>{children}</ChannelProvider>
-                            </AuthProvider>
-                        </ThemeProvider>
-                    </UserSettingsProvider>
-                </ServerConfigProvider>
+                            </ServerConfigProvider>
+                        </AuthProvider>
+                    </ThemeProvider>
+                </UserSettingsProvider>
                 <ReactQueryDevtools initialIsOpen={false} buttonPosition="bottom-left" />
             </QueryClientProvider>
         </I18nProvider>

+ 1 - 1
packages/dashboard/src/app/main.tsx

@@ -46,7 +46,7 @@ function InnerApp() {
         }
         setCustomFieldsMap(serverConfig.entityCustomFields);
         setHasSetCustomFieldsMap(true);
-    }, [serverConfig?.entityCustomFields]);
+    }, [serverConfig?.entityCustomFields.length]);
 
     return (
         <>

+ 12 - 1
packages/dashboard/src/app/routes/_authenticated.tsx

@@ -1,7 +1,8 @@
 import { AppLayout } from '@/components/layout/app-layout.js';
-import { createFileRoute, redirect } from '@tanstack/react-router';
+import { createFileRoute, redirect, useNavigate } from '@tanstack/react-router';
 import { AUTHENTICATED_ROUTE_PREFIX } from '@/constants.js';
 import * as React from 'react';
+import { useAuth } from '@/hooks/use-auth.js';
 
 export const Route = createFileRoute(AUTHENTICATED_ROUTE_PREFIX)({
     beforeLoad: ({ context, location }) => {
@@ -21,5 +22,15 @@ export const Route = createFileRoute(AUTHENTICATED_ROUTE_PREFIX)({
 });
 
 function AuthLayout() {
+    const navigate = useNavigate();
+    const { isAuthenticated } = useAuth();
+
+    if (!isAuthenticated) {
+        navigate({
+            to: '/login'
+        });
+        return <></>;
+    }
+
     return <AppLayout />;
 }

+ 4 - 4
packages/dashboard/src/lib/components/layout/nav-user.tsx

@@ -44,14 +44,14 @@ export function NavUser() {
         });
     };
 
+    const avatarFallback = useMemo(() => {
+        return user?.firstName?.charAt(0) ?? '' + user?.lastName?.charAt(0) ?? '';
+    }, [user]);
+
     if (!user) {
         return <></>;
     }
 
-    const avatarFallback = useMemo(() => {
-        return user.firstName.charAt(0) + user.lastName.charAt(0);
-    }, [user]);
-
     const isDevMode = (import.meta as any).env?.MODE === 'development';
 
     return (

+ 12 - 9
packages/dashboard/src/lib/providers/auth.tsx

@@ -69,17 +69,20 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
     const onLogoutSuccessFn = React.useRef<() => void>(() => {});
     const isAuthenticated = status === 'authenticated';
 
-    const { data: currentUserData, isLoading } = useQuery({
-        queryKey: ['currentUser'],
+    const { data: currentUserData, isLoading , error: currentUserError} = useQuery({
+        queryKey: ['currentUser', isAuthenticated],
         queryFn: () => api.query(CurrentUserQuery),
         retry: false,
+        staleTime: 1000,
     });
 
+    const currentUser = currentUserError ? undefined : currentUserData;
+
     React.useEffect(() => {
-        if (!settings.activeChannelId && currentUserData?.me?.channels?.length) {
-            setActiveChannelId(currentUserData.me.channels[0].id);
+        if (!settings.activeChannelId && currentUser?.me?.channels?.length) {
+            setActiveChannelId(currentUser.me.channels[0].id);
         }
-    }, [settings.activeChannelId, currentUserData?.me?.channels]);
+    }, [settings.activeChannelId, currentUser?.me?.channels]);
 
     const loginMutationFn = api.mutate(LoginMutation);
     const loginMutation = useMutation({
@@ -123,7 +126,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
 
     React.useEffect(() => {
         if (!isLoading) {
-            if (currentUserData?.me?.id) {
+            if (currentUser?.me?.id) {
                 setStatus('authenticated');
             } else {
                 setStatus('unauthenticated');
@@ -131,7 +134,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
         } else {
             setStatus('verifying');
         }
-    }, [isLoading, currentUserData]);
+    }, [isLoading, currentUser]);
 
     return (
         <AuthContext.Provider
@@ -139,8 +142,8 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
                 isAuthenticated,
                 authenticationError,
                 status,
-                user: currentUserData?.activeAdministrator,
-                channels: currentUserData?.me?.channels,
+                user: currentUser?.activeAdministrator,
+                channels: currentUser?.me?.channels,
                 login,
                 logout,
             }}

+ 1 - 0
packages/dashboard/src/lib/providers/channel-provider.tsx

@@ -73,6 +73,7 @@ export function ChannelProvider({ children }: { children: React.ReactNode }) {
     const { data: channelsData, isLoading: isChannelsLoading } = useQuery({
         queryKey: ['channels'],
         queryFn: () => api.query(ChannelsQuery),
+        retry: false,
     });
 
     // Set the selected channel and update localStorage

+ 7 - 1
packages/dashboard/src/lib/providers/server-config.tsx

@@ -1,5 +1,6 @@
 import { api } from '@/graphql/api.js';
 import { graphql } from '@/graphql/graphql.js';
+import { useAuth } from '@/hooks/use-auth.js';
 import { useQuery } from '@tanstack/react-query';
 import { ResultOf } from 'gql.tada';
 import React from 'react';
@@ -260,9 +261,14 @@ export interface ServerConfig {
 
 // create a provider for the global settings
 export const ServerConfigProvider = ({ children }: { children: React.ReactNode }) => {
+    const { user } = useAuth();
+    const queryKey = ['getServerConfig', user?.id];
     const { data } = useQuery({
-        queryKey: ['getServerConfig'],
+        queryKey,
         queryFn: () => api.query(getServerConfigDocument),
+        retry: false,
+        enabled: !!user?.id,
+        staleTime: 1000,
     });
     const value: ServerConfig = {
         availableLanguages: data?.globalSettings.availableLanguages ?? [],