@@ -15,6 +15,7 @@ import {
1515 AuthUiErrors ,
1616} from '../../../lib/auth-errors/auth-errors' ;
1717import { formatPhoneNumber } from '../../../lib/recovery-phone-utils' ;
18+ import { getHandledError , HandledError } from '../../../lib/error-utils' ;
1819
1920export const SigninRecoveryChoiceContainer = ( _ : RouteComponentProps ) => {
2021 const authClient = useAuthClient ( ) ;
@@ -27,14 +28,16 @@ export const SigninRecoveryChoiceContainer = (_: RouteComponentProps) => {
2728
2829 const [ numBackupCodes , setNumBackupCodes ] = useState < number > ( 0 ) ;
2930 const [ phoneData , setPhoneData ] = useState ( {
31+ phoneNumber : '' ,
32+ nationalFormat : '' ,
3033 maskedPhoneNumber : '' ,
3134 lastFourPhoneDigits : '' ,
3235 } ) ;
3336 const [ loading , setLoading ] = useState ( true ) ;
37+ const [ dataFetchError , setDataFetchError ] = useState < HandledError > ( ) ;
3438
3539 useEffect ( ( ) => {
3640 if ( ! signinState || ! signinState . sessionToken ) {
37- navigateWithQuery ( '/signin' ) ;
3841 return ;
3942 }
4043
@@ -47,54 +50,32 @@ export const SigninRecoveryChoiceContainer = (_: RouteComponentProps) => {
4750
4851 const { phoneNumber, nationalFormat } =
4952 await authClient . recoveryPhoneGet ( signinState . sessionToken ) ;
53+
5054 const { maskedPhoneNumber, lastFourPhoneDigits } = formatPhoneNumber ( {
5155 phoneNumber,
5256 nationalFormat,
5357 ftlMsgResolver,
5458 } ) ;
5559 setPhoneData ( {
60+ phoneNumber,
61+ nationalFormat,
5662 maskedPhoneNumber,
5763 lastFourPhoneDigits,
5864 } ) ;
59-
60- // whether or not the user has backup authentication codes,
61- // go directly to the backup authentication codes page if they don't have a phone number
62- // do not render the choice screen
63- if ( ! phoneNumber ) {
64- navigateWithQuery ( '/signin_recovery_code' , {
65- state : { signinState } ,
66- // ensure back button on signin_recovery_code page skips choice page and returns to signin_totp_code
67- replace : true ,
68- } ) ;
69- return ;
70- }
71-
72- if ( phoneNumber && ( ! count || count === 0 ) ) {
73- navigateWithQuery ( '/signin_recovery_phone' , {
74- state : { signinState, lastFourPhoneDigits } ,
75- // ensure back button on signin_recovery_code page skips choice page and returns to signin_totp_code
76- replace : true ,
77- } ) ;
78- }
7965 return ;
8066 } catch ( err ) {
81- if ( err . errno === AuthUiErrors . INVALID_TOKEN . errno ) {
82- navigateWithQuery ( '/signin' ) ;
83- return ;
84- }
85- // if there was another error fetching available recovery methods, go to backup authentication codes page
86- navigateWithQuery ( '/signin_recovery_code' , {
87- state : { signinState } ,
88- // ensure back button on signin_recovery_code page skips choice page and returns to signin_totp_code
89- replace : true ,
90- } ) ;
67+ const handledError = getHandledError ( err ) ;
68+ setDataFetchError ( handledError . error ) ;
9169 return ;
9270 } finally {
9371 setLoading ( false ) ;
9472 }
9573 } ;
9674 fetchData ( ) ;
97- } , [ authClient , signinState , navigateWithQuery , ftlMsgResolver ] ) ;
75+ // excluding ftlMsgResolver as it is causing re-renders
76+ // but should be stable and not changing at runtime
77+ // eslint-disable-next-line react-hooks/exhaustive-deps
78+ } , [ authClient , signinState ] ) ;
9879
9980 const handlePhoneChoice = async ( ) => {
10081 if ( ! signinState ) {
@@ -115,16 +96,43 @@ export const SigninRecoveryChoiceContainer = (_: RouteComponentProps) => {
11596 }
11697 } ;
11798
99+ if ( ! signinState || ! signinState . sessionToken ) {
100+ navigateWithQuery ( '/signin' ) ;
101+ return ;
102+ }
103+
118104 if ( loading ) {
119105 return < LoadingSpinner fullScreen /> ;
120106 }
121107
122- if (
123- ! signinState ||
124- ! phoneData . maskedPhoneNumber ||
125- ! phoneData . lastFourPhoneDigits
126- ) {
127- return < LoadingSpinner fullScreen /> ;
108+ if ( dataFetchError ) {
109+ if ( dataFetchError . errno === AuthUiErrors . INVALID_TOKEN . errno ) {
110+ navigateWithQuery ( '/signin' ) ;
111+ return ;
112+ }
113+ // if there was another error fetching available recovery methods, go to backup authentication codes page
114+ navigateWithQuery ( '/signin_recovery_code' , {
115+ state : { signinState } ,
116+ // ensure back button on signin_recovery_code page skips choice page and returns to signin_totp_code
117+ replace : true ,
118+ } ) ;
119+ }
120+ if ( ! phoneData . phoneNumber ) {
121+ navigateWithQuery ( '/signin_recovery_code' , {
122+ state : { signinState } ,
123+ // ensure back button on signin_recovery_code page skips choice page and returns to signin_totp_code
124+ replace : true ,
125+ } ) ;
126+ return ;
127+ } else if ( ! numBackupCodes || numBackupCodes === 0 ) {
128+ navigateWithQuery ( '/signin_recovery_phone' , {
129+ state : {
130+ signinState,
131+ lastFourPhoneDigits : phoneData . lastFourPhoneDigits ,
132+ } ,
133+ // ensure back button on signin_recovery_code page skips choice page and returns to signin_totp_code
134+ replace : true ,
135+ } ) ;
128136 }
129137
130138 return (
0 commit comments