From d55faf7ca6251eaa1e6ec91e1b69f3af57056e7d Mon Sep 17 00:00:00 2001 From: Elias Sommer <60005105+eliassommer@users.noreply.github.com> Date: Wed, 21 Feb 2024 09:06:47 +0100 Subject: [PATCH 1/5] fix(Authentication): faulty session handling (#22) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Elias Sommer <„sommer_elias@outlook.de“> --- navigation/StackNavigator.tsx | 55 +++++++++++++++++---------- package-lock.json | 31 +++++++++++++++ screens/SignInScreen/SignInScreen.tsx | 36 ++++++++---------- screens/TestScreen/TestScreen.tsx | 32 +++++++++++++++- 4 files changed, 112 insertions(+), 42 deletions(-) diff --git a/navigation/StackNavigator.tsx b/navigation/StackNavigator.tsx index 437173c..92dc122 100644 --- a/navigation/StackNavigator.tsx +++ b/navigation/StackNavigator.tsx @@ -1,36 +1,51 @@ -// StackNavigator.tsx +import React, { useEffect, useState } from 'react'; +import { View, ActivityIndicator } from 'react-native'; +import AsyncStorage from '@react-native-async-storage/async-storage'; +import { NavigationContainer } from '@react-navigation/native'; +import { createStackNavigator, StackNavigationProp } from '@react-navigation/stack'; +import { useNavigation } from '@react-navigation/native'; -import React from "react"; -import { createStackNavigator } from "@react-navigation/stack"; -import { NavigationContainer } from "@react-navigation/native"; -import { getUserToken } from "../utils/asyncStorage"; // Screens -import TestScreen from "../screens/TestScreen/TestScreen"; -import SignInScreen from "../screens/SignInScreen/SignInScreen"; -import AsyncStorage from "@react-native-async-storage/async-storage"; -import HomeScreenEmpty from "../screens/HomeScreen/HomeScreenEmpty"; +import TestScreen from '../screens/TestScreen/TestScreen'; +import SignInScreen from '../screens/SignInScreen/SignInScreen'; // Types for Navigation export type RootStackParamList = { - HomeScreenEmpty: undefined; - SignIn: undefined; + AuthLoading: undefined; Test: undefined; + SignIn: undefined; }; const Stack = createStackNavigator(); const StackNavigator: React.FC = () => { + const [isLoading, setIsLoading] = useState(true); + const [isSignedIn, setIsSignedIn] = useState(false); + + useEffect(() => { + const checkToken = async () => { + const userToken = await AsyncStorage.getItem('userToken'); + setIsSignedIn(!!userToken); + setIsLoading(false); + }; + + checkToken(); + }, []); + + if (isLoading) { + return ( + + + + ); + } + return ( - - {/* DevNote: We need to add token validation when we sell the App (Security Concerns)*/} - {getUserToken() === null ? ( - - ) : ( - // ToDo: Add Bottom Tab Navigator here - - )} - + + + null}} /> + {/* Weitere Screens */} ); diff --git a/package-lock.json b/package-lock.json index be0a0c3..2f6a65f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@expo-google-fonts/roboto": "^0.2.3", "@fluentui/react-native-icons": "^2.0.224", "@gorhom/bottom-sheet": "^4.6.0", + "@react-native-async-storage/async-storage": "1.18.2", "@react-navigation/native": "^6.1.9", "@react-navigation/stack": "^6.3.20", "@rneui/base": "^4.0.0-rc.7", @@ -4647,6 +4648,17 @@ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, + "node_modules/@react-native-async-storage/async-storage": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-1.18.2.tgz", + "integrity": "sha512-dM8AfdoeIxlh+zqgr0o5+vCTPQ0Ru1mrPzONZMsr7ufp5h+6WgNxQNza7t0r5qQ6b04AJqTlBNixTWZxqP649Q==", + "dependencies": { + "merge-options": "^3.0.4" + }, + "peerDependencies": { + "react-native": "^0.0.0-0 || 0.60 - 0.72 || 1000.0.0" + } + }, "node_modules/@react-native-community/cli": { "version": "11.3.7", "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-11.3.7.tgz", @@ -10335,6 +10347,14 @@ "node": ">=8" } }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -11798,6 +11818,17 @@ "resolved": "https://registry.npmjs.org/memory-cache/-/memory-cache-0.2.0.tgz", "integrity": "sha512-OcjA+jzjOYzKmKS6IQVALHLVz+rNTMPoJvCztFaZxwG14wtAW7VRZjwTQu06vKCYOxh4jVnik7ya0SXTB0W+xA==" }, + "node_modules/merge-options": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz", + "integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==", + "dependencies": { + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", diff --git a/screens/SignInScreen/SignInScreen.tsx b/screens/SignInScreen/SignInScreen.tsx index 1fd5583..10876ad 100644 --- a/screens/SignInScreen/SignInScreen.tsx +++ b/screens/SignInScreen/SignInScreen.tsx @@ -38,32 +38,28 @@ const Divider = (props: any) => { }; const SignInScreen: React.FC = () => { - const navigation = useNavigation(); + const navigation = useNavigation(); // Properties const [email, setEmail] = useState("elias.unity@gmail.com"); const [password, setPassword] = useState("1234"); - const onSignInPress = () => { - signInWithEmailAndPassword(auth, email, password) - .then(async (userCredential: UserCredential) => { - await AsyncStorage.setItem("userToken", userCredential.user.uid); - - userCredential.user - .getIdToken() - .then(async (token: string) => { - await AsyncStorage.setItem("userToken", token); - }) - .catch((error) => { - alert(error); - }); - - navigation.navigate("Test"); - }) - .catch((error) => { - alert(error); - }); + const onSignInPress = async () => { + try { + const userCredential: UserCredential = await signInWithEmailAndPassword( + auth, + email, + password + ); + const user = userCredential.user; + console.log(user); + await AsyncStorage.setItem("userToken", user?.uid); + navigation.navigate("Test"); + } catch (error) { + console.log(error); + } }; + return ( diff --git a/screens/TestScreen/TestScreen.tsx b/screens/TestScreen/TestScreen.tsx index ebca337..0b557f3 100644 --- a/screens/TestScreen/TestScreen.tsx +++ b/screens/TestScreen/TestScreen.tsx @@ -1,10 +1,38 @@ import React from "react"; -import { View, Text } from "react-native"; +import { View, Text, Button } from "react-native"; +import { removeToken } from "../../utils/asyncStorage"; +import AsyncStorage from "@react-native-async-storage/async-storage"; +import { + StackNavigationProp, +} from "@react-navigation/stack"; +import { RootStackParamList } from "../../navigation/StackNavigator"; +import { useNavigation } from "@react-navigation/native"; + +type TestScreenNavigationProp = StackNavigationProp< + RootStackParamList, + "Test" +>; + +type Props = { + navigation: TestScreenNavigationProp; +}; + +const TestScreen: React.FC = () => { + + const navigation = useNavigation(); + const logout = async () => { + try { + await removeToken(); + navigation.navigate("SignIn"); + } catch (error) { + console.log(error); + } + }; -const TestScreen: React.FC = () => { return ( Test Screen +