Skip to content

Commit

Permalink
Merge branch 'frankreed/foreignManagement4_overhaul_auth_redirects' i…
Browse files Browse the repository at this point in the history
…nto frankreed/foreignManagement5_invite_tab

# Conflicts:
#	app/segments/(team)/chooseTeam.js
  • Loading branch information
FrankreedX committed Aug 13, 2024
2 parents e1971d6 + fca54a9 commit e342ea5
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 25 deletions.
17 changes: 15 additions & 2 deletions app/(auth)/signup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { Link, useLocalSearchParams } from "expo-router";
import { createUserWithEmailAndPassword, updateProfile } from "firebase/auth";
import {
createUserWithEmailAndPassword,
sendEmailVerification,
updateProfile,
} from "firebase/auth";
import { doc, setDoc } from "firebase/firestore";
import { useState } from "react";
import {
Expand Down Expand Up @@ -32,7 +36,7 @@ export default function SignUp() {
const [password, setPassword] = useState("");
const [passwordCheck, setPasswordCheck] = useState("");

const { showDialog } = useAlertContext();
const { showDialog, showSnackBar } = useAlertContext();

const { height } = useWindowDimensions();

Expand All @@ -56,6 +60,15 @@ export default function SignUp() {
email: email,
});

try {
await sendEmailVerification(auth.currentUser);
console.log("Verification Email Sent!");
showSnackBar("Verification Email Sent!");
} catch {
console.log("Error sending verification email: ", e);
showDialog("Error", getErrorString(e));
}

setCurrentUserId(userCredential.user.uid);
setCurrentUserInfo({ ...userCredential.user, displayName: name });

Expand Down
2 changes: 1 addition & 1 deletion app/content/profile/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ function Index() {
newPassword,
newPasswordCheck,
passwordInputVisible,
userData.name,
userData,
userEmail,
],
);
Expand Down
117 changes: 100 additions & 17 deletions app/segments/(team)/chooseTeam.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { useQueryClient } from "@tanstack/react-query";
import { router } from "expo-router";
import { signOut as signoutFireBase } from "firebase/auth";
import { useMemo } from "react";
import { ScrollView, Text, View } from "react-native";
import {
onIdTokenChanged,
sendEmailVerification,
signOut as signoutFireBase,
} from "firebase/auth";
import { useCallback, useEffect, useMemo, useState } from "react";
import { RefreshControl, ScrollView, Text, View } from "react-native";
import { Button } from "react-native-paper";
import { SafeAreaView } from "react-native-safe-area-context";
import { themeColors } from "~/Constants";
import { getErrorString } from "~/Utility";
import ErrorComponent from "~/components/errorComponent";
import Loading from "~/components/loading";
import RefreshInvalidate from "~/components/refreshInvalidate";
import { useAlertContext } from "~/context/Alert";
import { useAuthContext } from "~/context/Auth";
import { addToTeam } from "~/dbOperations/addToTeam";
Expand All @@ -32,7 +35,7 @@ function ChooseTeam() {
} = useAuthContext();
const queryClient = useQueryClient();

const { showDialog } = useAlertContext();
const { showDialog, showSnackBar } = useAlertContext();

const {
data: blacklist,
Expand Down Expand Up @@ -68,13 +71,61 @@ function ChooseTeam() {
return "neutral";
}, [blacklist, currentUserId, invitelist, waitlist]); //blacklist, waitlist, invitelist, neutral

const [verified, setVerified] = useState(false);
const [refreshing, setRefreshing] = useState(false);

const invalidateKeys = [
["invitelist"],
["blacklist"],
["waitlist"],
["userInfo", { userId: currentUserId }],
];

async function handleSignOut() {
try {
await signoutFireBase(auth);
signOut();
} catch (e) {
console.log(e);
showDialog("Error", getErrorString(e));
}
}

useEffect(() => {
const unregisterAuthObserver = onIdTokenChanged(auth, async (user) => {
if (user) {
if (user.emailVerified) {
setVerified(true);
showSnackBar("Email successfully verified.");
clearInterval(intervalId); // Stop the interval when email is verified
unregisterAuthObserver(); // Unregister the auth observer
} else {
setVerified(false);
console.log("Error: Email Not Verified Yet, Try Again");
}
}
});

// Set up an interval to check email verification every 10 seconds
const intervalId = setInterval(async () => {
if (auth.currentUser) {
await auth.currentUser.reload();
}
}, 10000); // 10,000 ms = 10 seconds

return () => {
clearInterval(intervalId); // Clean up the interval when component unmounts
unregisterAuthObserver(); // Unregister the auth observer
};
}, []);

Check warning on line 120 in app/segments/(team)/chooseTeam.js

View workflow job for this annotation

GitHub Actions / prettier-check

React Hook useEffect has a missing dependency: 'showSnackBar'. Either include it or remove the dependency array

const onRefresh = useCallback(async () => {
setRefreshing(true);
await auth.currentUser.reload();
await invalidateMultipleKeys(queryClient, invalidateKeys);
setRefreshing(false);
}, []);

Check warning on line 127 in app/segments/(team)/chooseTeam.js

View workflow job for this annotation

GitHub Actions / prettier-check

React Hook useCallback has missing dependencies: 'invalidateKeys' and 'queryClient'. Either include them or remove the dependency array

if (blacklistIsLoading || waitlistIsLoading || invitelistIsLoading) {
return <Loading />;
}
Expand All @@ -87,16 +138,6 @@ function ChooseTeam() {
);
}

async function handleSignOut() {
try {
await signoutFireBase(auth);
signOut();
} catch (e) {
console.log(e);
showDialog("Error", getErrorString(e));
}
}

return (
<SafeAreaView
style={{
Expand All @@ -110,9 +151,51 @@ function ChooseTeam() {
alignItems: "center",
flexGrow: 1,
}}
refreshControl={<RefreshInvalidate invalidateKeys={invalidateKeys} />}
refreshControl={
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
}
>
{state === "blacklist" ? (
{!verified ? (
<View
style={{
alignItems: "center",
justifyContent: "center",
}}
>
<Text>Waiting for email verification...</Text>
<Button
style={{
backgroundColor: themeColors.accent,
borderRadius: 12,
marginTop: 20,
}}
onPress={async () => {
setLoading(true);
try {
await sendEmailVerification(auth.currentUser);
console.log("Verification Email Sent!");
showSnackBar("Verification Email Sent!");
} catch (e) {
console.log("Error sending verification email: ", e);
showDialog("Error", getErrorString(e));
}
setLoading(false);
}}
loading={loading}
textColor="white"
>
<Text
style={{
color: themeColors.highlight,
fontSize: 18,
textAlign: "center",
}}
>
Resend Verification Email
</Text>
</Button>
</View>
) : state === "blacklist" ? (
<Text
style={{
fontSize: 16,
Expand Down
12 changes: 9 additions & 3 deletions context/Auth.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useRouter, useSegments } from "expo-router";
import { onAuthStateChanged } from "firebase/auth";
import { onIdTokenChanged } from "firebase/auth";
import { createContext, useContext, useEffect, useState } from "react";
import { auth } from "~/firebaseConfig";

Expand All @@ -11,6 +11,7 @@ const AuthContext = createContext({
currentUserId: null,
currentTeamId: null,
currentUserInfo: null,
currentUserVerified: false,
});

export function useAuthContext() {
Expand All @@ -35,12 +36,13 @@ export const AuthProvider = ({ children }) => {
const [currentUserId, setCurrentUserId] = useState(null);
const [currentUserInfo, setCurrentUserInfo] = useState(null);
const [currentTeamId, setCurrentTeamId] = useState("1");
const [currentUserVerified, setCurrentUserVerified] = useState(false);

useProtectedRoute(currentUserId);

useEffect(() => {
//if this code is not in here, it'll run for infinite times
onAuthStateChanged(auth, (newlyLoggedInUser) => {
onIdTokenChanged(auth, (newlyLoggedInUser) => {
// test user login (yarn test)
// If you sign out, reload or click "sign in" to login as test user
// Signout functionality for test user is buggy, chance of auto-logging back in
Expand All @@ -55,10 +57,13 @@ export const AuthProvider = ({ children }) => {
setCurrentUserId(newlyLoggedInUser["uid"] ?? "Error (uid)");
setCurrentUserInfo(newlyLoggedInUser ?? {});
console.log("user changed. userId:", newlyLoggedInUser["uid"]);
if (auth.currentUser.emailVerified) {
setCurrentUserVerified(true);
}
}
}
});
}, []);
}, [currentUserVerified]);
return (
<AuthContext.Provider
value={{
Expand All @@ -78,6 +83,7 @@ export const AuthProvider = ({ children }) => {
setCurrentUserInfo(userInfo);
},
currentUserInfo,
currentUserVerified,
}}
>
{children}
Expand Down
5 changes: 3 additions & 2 deletions dbOperations/hooks/useUserInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export const useUserInfo = ({
enabled = true,
} = {}) => {
const segments = useSegments();
const { currentTeamId, currentUserId } = useAuthContext();
const { currentTeamId, currentUserId, currentUserVerified } =
useAuthContext();
const week_milliseconds = 604800000;
const currentDate = new Date();
const currentDateTime = currentDate.getTime();
Expand All @@ -33,7 +34,7 @@ export const useUserInfo = ({
);
const data = querySnapshot.data();
const inChooseTeam = segments.at(-1) === "chooseTeam";
if (!data) {
if (!data || !currentUserVerified) {
if (currentUserId === userId && !inChooseTeam) {
router.replace("segments/(team)/chooseTeam");
}
Expand Down

0 comments on commit e342ea5

Please sign in to comment.