Skip to content

Commit

Permalink
fix: refreshing app no longer logging user out
Browse files Browse the repository at this point in the history
  • Loading branch information
ezeikel committed Jan 20, 2025
1 parent 89daea4 commit 2791d10
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 79 deletions.
14 changes: 1 addition & 13 deletions apps/mobile/app/(authenticated)/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,11 @@
import { useEffect, useState } from "react";
import { Text } from "react-native";
import { Redirect, Stack } from "expo-router";
import { StatusBar } from "expo-status-bar";
import { useAuthContext } from "@/contexts/auth";
import PushNotificationInitialiser from "@/components/PushNotificationInitialiser";

const AppLayout = () => {
const [authToken, setAuthToken] = useState<string | null>(null);
const { isAuthenticated, isLoading, user, getAuthToken } = useAuthContext();

useEffect(() => {
const checkToken = async () => {
const token = await getAuthToken();
setAuthToken(token);
};

checkToken();
}, []);
const { isAuthenticated, isLoading, user } = useAuthContext();

if (isLoading) {
return <Text>Loading...</Text>;
Expand All @@ -33,7 +22,6 @@ const AppLayout = () => {
</Stack>
<StatusBar style="auto" />
<PushNotificationInitialiser userId={user?.id} />
<Text>Current auth token: {authToken}</Text>
</>
);
};
Expand Down
20 changes: 4 additions & 16 deletions apps/mobile/app/sign-in.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,19 @@
import { Text, View } from "react-native";
import { View } from "react-native";
import { router } from "expo-router";
import { SafeAreaView } from "react-native-safe-area-context";
import { GoogleSigninButton } from "@react-native-google-signin/google-signin";
import { useAuthContext } from "@/contexts/auth";
import { useEffect, useState } from "react";
import logger from "@/utils/logger";

const AuthScreen = () => {
const { signIn } = useAuthContext();
const { getAuthToken } = useAuthContext();
const [authToken, setAuthToken] = useState<string | null>(null);

useEffect(() => {
const checkToken = async () => {
const token = await getAuthToken();
setAuthToken(token);
};

checkToken();
}, []);

const handleSignIn = async () => {
try {
await signIn();
router.replace("/");
} catch (error) {
console.error("Sign in error:", error);
} catch (error: unknown) {
logger.error("Sign in error:", error as Error);
}
};

Expand All @@ -36,7 +25,6 @@ const AuthScreen = () => {
color={GoogleSigninButton.Color.Light}
onPress={handleSignIn}
/>
<Text>Current auth token: {authToken}</Text>
</View>
</SafeAreaView>
);
Expand Down
105 changes: 55 additions & 50 deletions apps/mobile/contexts/auth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ export const AuthContext = createContext<AuthContextType>({
});

export const AuthContextProvider = ({ children }: AuthContextProviderProps) => {
const router = useRouter();
const [isAuthenticated, setIsAuthenticated] = useState<boolean>(false);
const [isLoading, setIsLoading] = useState<boolean>(true);
const [user, setUser] = useState<AuthUser | null>(null);
const router = useRouter();
const [authToken, setAuthToken] = useState<string | null>(null);
const queryClient = useQueryClient();

Expand All @@ -67,54 +67,6 @@ export const AuthContextProvider = ({ children }: AuthContextProviderProps) => {
});
};

useEffect(() => {
configureGoogleSignIn();
}, []);

const checkAuth = async () => {
try {
setIsLoading(true);
const authToken = await SecureStore.getItemAsync("authToken");

if (!authToken) {
setIsAuthenticated(false);
router.replace("/sign-in");
return;
}

if (currentUserQuery.isLoading) {
return;
}

if (currentUserQuery.error) {
throw new Error("Failed to validate token");
}

if (currentUserQuery.data) {
setUser(currentUserQuery.data);
setIsAuthenticated(true);
router.replace("/");
} else {
throw new Error("User not found");
}
} catch (error: unknown) {
logger.error("Error checking authentication:", error as Error);
await SecureStore.deleteItemAsync("authToken");
setIsAuthenticated(false);
router.replace("/sign-in");
} finally {
setIsLoading(false);
}
};

useEffect(() => {
checkAuth();

// periodic token validation (every 10 minutes)
const intervalId = setInterval(checkAuth, 10 * 60 * 1000);
return () => clearInterval(intervalId);
}, [authToken]);

const signIn = async () => {
try {
setIsLoading(true);
Expand All @@ -137,8 +89,8 @@ export const AuthContextProvider = ({ children }: AuthContextProviderProps) => {
},
});

// store token
await SecureStore.setItemAsync("authToken", result.token);
setAuthToken(result.token);
setUser(result.user);
setIsAuthenticated(true);
router.replace("/");
Expand All @@ -165,6 +117,7 @@ export const AuthContextProvider = ({ children }: AuthContextProviderProps) => {
await SecureStore.deleteItemAsync("authToken");
setUser(null);
setIsAuthenticated(false);
setAuthToken(null);
router.replace("/sign-in");

// clear all queries
Expand All @@ -178,6 +131,52 @@ export const AuthContextProvider = ({ children }: AuthContextProviderProps) => {

const getAuthToken = async () => SecureStore.getItemAsync("authToken");

useEffect(() => {
configureGoogleSignIn();
}, []);

useEffect(() => {
const checkAuth = async () => {
try {
setIsLoading(true);
const storedToken = await getAuthToken();

if (!storedToken) {
setIsAuthenticated(false);
setAuthToken(null);
router.replace("/sign-in");
return;
}

// check if user is authenticated
const userResult = await currentUserQuery.refetch();

if (userResult.data) {
setUser(userResult.data);
setAuthToken(storedToken);
setIsAuthenticated(true);
router.replace("/");
} else {
throw new Error("User not found");
}
} catch (error: unknown) {
logger.error("Error checking authentication:", error as Error);
await SecureStore.deleteItemAsync("authToken");
setAuthToken(null);
setIsAuthenticated(false);
router.replace("/sign-in");
} finally {
setIsLoading(false);
}
};

checkAuth();

// periodic token validation (every 10 minutes)
const intervalId = setInterval(checkAuth, 10 * 60 * 1000);
return () => clearInterval(intervalId);
}, []);

useEffect(() => {
const getToken = async () => {
const token = await getAuthToken();
Expand All @@ -186,6 +185,12 @@ export const AuthContextProvider = ({ children }: AuthContextProviderProps) => {
getToken();
}, []);

useEffect(() => {
if (authToken) {
SecureStore.setItemAsync("authToken", authToken);
}
}, [authToken]);

return (
<AuthContext.Provider
value={{
Expand Down

0 comments on commit 2791d10

Please sign in to comment.