import { setInternetCredentials , getInternetCredentials , resetInternetCredentials , } from 'react-native-keychain' ; import type { Result as RNKeychainResult } from 'react-native-keychain' ; import buildFormData from './formdata' ; import { OLECARD_AUTH_URL } from './financials/urls' ; const SIS_LOGIN_KEY = 'stolaf.edu' ; const empty = ( ) => ( { } ) ; export type Credentials = { username : string ; password : string ; } ; export type MaybeCredentials = { username ? : string ; password ? : string ; } ; export function saveLoginCredentials ( { username , password , } ) { return setInternetCredentials ( SIS_LOGIN_KEY , username , password ) . catch ( empty ) ; } export function loadLoginCredentials ( ) { return getInternetCredentials ( SIS_LOGIN_KEY ) . catch ( empty ) ; } export function clearLoginCredentials ( ) { return resetInternetCredentials ( SIS_LOGIN_KEY ) . catch ( empty ) ; } export type LoginResultEnum = 'success' | 'network' | 'bad-credentials' | 'no-credentials' | 'server-error' | 'other' ; type Args = { attempts ? : number ; } ; export async function performLogin ( { attempts = 0 , } = { } ) { const { username , password } = await loadLoginCredentials ( ) ; if ( ! username || ! password ) { return 'no-credentials' ; } const form = buildFormData ( { username , password } ) ; try { const { status : statusCode } = await fetch ( OLECARD_AUTH_URL , { method : 'POST' , body : form , credentials : 'include' , cache : 'no-store' , throwHttpErrors : false , } ) ; if ( statusCode >= 400 && statusCode < 500 ) { return 'bad-credentials' ; } if ( statusCode >= 500 && statusCode < 600 ) { return 'server-error' ; } if ( statusCode < 200 || statusCode >= 300 ) { return 'other' ; } return 'success' ; } catch ( err ) { const wasNetworkFailure = err . message === 'Network request failed' ; if ( wasNetworkFailure ) { if ( attempts > 0 ) { return performLogin ( { attempts : attempts - 1 } ) ; } return 'network' ; } return 'other' ; } }