// This file handles the authentication state. import { Session as KratosSession } from '@oryd/kratos-client' import * as SecureStore from 'expo-secure-store' import AsyncStore from '@react-native-community/async-storage' import { Platform } from 'react-native' // The key under which the session is being stored const userSessionName = 'user_session' // The session type export type SessionContext = { // The session token session_token: string // The session itself session: KratosSession } | null // getAuthenticatedSession returns a promise with the session of the authenticated user, if the // user is authenticated or null is the user is not authenticated. // // If an error (e.g. network error) occurs, the promise rejects with an error. export const getAuthenticatedSession = (): Promise => { const parse = (sessionRaw: string | null): SessionContext => { if (!sessionRaw) { return null } // sessionRaw is a JSON String that needs to be parsed. return JSON.parse(sessionRaw) } let p = AsyncStore.getItem(userSessionName) if (Platform.OS !== 'web') { // We can use SecureStore if not on web instead! p = SecureStore.getItemAsync(userSessionName) } return p.then(parse) } // Sets the session. export const setAuthenticatedSession = ( session: SessionContext ): Promise => { if (!session) { return killAuthenticatedSession() } if (Platform.OS === 'web') { // SecureStore is not available on the web platform. We need to use AsyncStore // instead. return AsyncStore.setItem(userSessionName, JSON.stringify(session)) } return ( SecureStore // The SecureStore only supports strings so we encode the session. .setItemAsync(userSessionName, JSON.stringify(session)) ) } // Removes the session from the store. export const killAuthenticatedSession = () => { if (Platform.OS === 'web') { // SecureStore is not available on the web platform. We need to use AsyncStore // instead. return AsyncStore.removeItem(userSessionName) } return SecureStore.deleteItemAsync(userSessionName) }