|
@@ -5,10 +5,12 @@ import jwt_decode from 'jwt-decode'
|
|
|
import React, { createContext, useContext, useEffect, useMemo, useState } from "react"
|
|
|
import { useQueryClient } from "react-query"
|
|
|
import { API_URL, reportAxiosError } from "../../utils/RequestUtils"
|
|
|
-import { Landmark } from "../landmarks"
|
|
|
+import { Landmark, } from "../landmarks"
|
|
|
import { queryKeys } from "../query-keys"
|
|
|
import {v4} from 'uuid'
|
|
|
import { ErrorMessage } from "formik"
|
|
|
+import { Alert } from "react-native"
|
|
|
+import { navigate } from "../../navigation/RootNavigator"
|
|
|
|
|
|
export const SECURESTORE_ACCESSTOKEN = "access"
|
|
|
export const SECURESTORE_REFRESHTOKEN = "refresh"
|
|
@@ -55,8 +57,9 @@ interface AuthenticationResult {
|
|
|
}
|
|
|
|
|
|
interface GlobalAlert {
|
|
|
+ title: string
|
|
|
message: string
|
|
|
- type: 'success' | 'error'
|
|
|
+ type: 'success' | 'error' | 'warning'
|
|
|
callback: () => void
|
|
|
}
|
|
|
|
|
@@ -96,7 +99,7 @@ export const AuthContextProvider: React.FC = ({children}) => {
|
|
|
const [userId, setUserId] = useState<string>()
|
|
|
const [anonUserId, setAnonUserId] = useState<string>()
|
|
|
const [loading, setLoading] = useState<boolean>(false)
|
|
|
- const [message, setMessage] = useState<string>('')
|
|
|
+ const [alert, setAlert] = useState<GlobalAlert>()
|
|
|
|
|
|
const queryClient = useQueryClient()
|
|
|
|
|
@@ -143,6 +146,23 @@ export const AuthContextProvider: React.FC = ({children}) => {
|
|
|
loadAuthStateFromStorageOnAppLoad()
|
|
|
}, [])
|
|
|
|
|
|
+ useEffect(() => {
|
|
|
+ if (alert) {
|
|
|
+ const alertTitle = alert.title
|
|
|
+ Alert.alert(alertTitle, alert.message, [{text: 'OK', onPress: alert.callback}])
|
|
|
+ setAlert(undefined)
|
|
|
+ }
|
|
|
+ }, [alert])
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ const convertExistingAnonymousLandmarksOnAccessTokenChange = async () => {
|
|
|
+ if (accessToken && anonUserId) {
|
|
|
+ await convertExistingAnonymousLandmarks()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ convertExistingAnonymousLandmarksOnAccessTokenChange()
|
|
|
+ }, [accessToken])
|
|
|
+
|
|
|
const setAccessTokenAsync = async (token: string) => {
|
|
|
setAccessToken(token)
|
|
|
setStorageItem(SECURESTORE_ACCESSTOKEN, token)
|
|
@@ -237,11 +257,6 @@ export const AuthContextProvider: React.FC = ({children}) => {
|
|
|
await setRefreshTokenAsync(tokenResponse.refresh_token);
|
|
|
await setUserIdAsync(idToken.sub)
|
|
|
|
|
|
- // TODO: check for anonymous landmarks on the server, and display a notification if there are any asking the user to convert them
|
|
|
- await checkForAnonymousLandmarks()
|
|
|
-
|
|
|
- setAnonUserId('')
|
|
|
-
|
|
|
console.log('[Authentication]: Tokens successfully retrieved.')
|
|
|
|
|
|
|
|
@@ -249,14 +264,14 @@ export const AuthContextProvider: React.FC = ({children}) => {
|
|
|
} catch (error) {
|
|
|
reportAxiosError("Something went wrong when retrieving access token", error);
|
|
|
setLoading(false)
|
|
|
- setError("Something went wrong while logging in. Please try again.")
|
|
|
+ setAlert({title:"Error", message: "Something went wrong when retrieving access token", callback: () => {}, type: 'error'})
|
|
|
}
|
|
|
}
|
|
|
else if (response.type == "cancel") {
|
|
|
setLoading(false)
|
|
|
}
|
|
|
else {
|
|
|
- setError("Something went wrong while logging in. Please try again.")
|
|
|
+ setAlert({title: 'Error', message: "Something went wrong while logging in. Please try again.", callback: () => {}, type: 'error'})
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -274,11 +289,12 @@ export const AuthContextProvider: React.FC = ({children}) => {
|
|
|
});
|
|
|
|
|
|
queryClient.setQueryData(queryKeys.getOwnedProfile, null)
|
|
|
+ await setAnonUserId(await getItemAsync(SECURESTORE_ANONID))
|
|
|
await clearAuthStorage()
|
|
|
|
|
|
} catch (error) {
|
|
|
reportAxiosError("Something went wrong when logging out", error);
|
|
|
- setError("Something went wrong while logging out. Please try again.")
|
|
|
+ setAlert({title: 'Error', message: "Something went wrong while logging out. Please try again.", callback: () => {}, type: 'error'})
|
|
|
}
|
|
|
setLoading(false)
|
|
|
}
|
|
@@ -320,9 +336,7 @@ export const AuthContextProvider: React.FC = ({children}) => {
|
|
|
return owned
|
|
|
}
|
|
|
|
|
|
- const createGlobalAlert = (message: string) => {
|
|
|
-
|
|
|
- const checkForAnonymousLandmarks = async () => {
|
|
|
+ const convertExistingAnonymousLandmarks = async () => {
|
|
|
try {
|
|
|
const response = await sendApiRequestAsync({
|
|
|
axiosConfig: {
|
|
@@ -334,10 +348,33 @@ export const AuthContextProvider: React.FC = ({children}) => {
|
|
|
})
|
|
|
|
|
|
if (response?.data?.has_landmark) {
|
|
|
+ // send request to convert landarks
|
|
|
+ await sendApiRequestAsync({
|
|
|
+ axiosConfig: {
|
|
|
+ method: 'POST',
|
|
|
+ url: `/api/landmarks/convert/${anonUserId}/`
|
|
|
+ },
|
|
|
+ authorized: true,
|
|
|
+ errorMessage: 'Something went wrong when converting anonymous landmarks'
|
|
|
+ })
|
|
|
|
|
|
+ setAnonUserId('')
|
|
|
+
|
|
|
+ setAlert({
|
|
|
+ title: 'Heads up',
|
|
|
+ message: "It looks like you added some landmarks before creating an account, so those landmarks are now owned by your newly created account.",
|
|
|
+ callback: () => {},
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
}
|
|
|
} catch (error) {
|
|
|
reportAxiosError("[Authentication]: Error when checking for anonymous landmarks", error);
|
|
|
+ setAlert({
|
|
|
+ title: 'Error',
|
|
|
+ message: "Failed to convert your old anonymous landmarks to your account. Please try again manually by going to Account -> Information -> Transfer anonymous landmarks.",
|
|
|
+ callback: () => navigate("Account"),
|
|
|
+ type: 'error'
|
|
|
+ })
|
|
|
return false
|
|
|
}
|
|
|
}
|
|
@@ -354,15 +391,14 @@ export const AuthContextProvider: React.FC = ({children}) => {
|
|
|
refreshToken,
|
|
|
userId,
|
|
|
loading,
|
|
|
- error,
|
|
|
anonUserId,
|
|
|
setLoading,
|
|
|
- setError,
|
|
|
+ setAlert,
|
|
|
sendApiRequestAsync,
|
|
|
login,
|
|
|
logout,
|
|
|
refreshAccessToken,
|
|
|
- }), [accessToken, refreshToken, userId, loading, error, anonUserId])
|
|
|
+ }), [accessToken, refreshToken, userId, loading, anonUserId])
|
|
|
|
|
|
return (
|
|
|
<AuthContext.Provider value={authState}>
|