@@ -22,9 +22,11 @@ import {
2222 type ConfirmEmailResponse ,
2323 Roles ,
2424 Products ,
25+ AuthorizationError ,
2526} from "utils/atlas" ;
2627
2728import { isUndefined } from "src/utils" ;
29+ import { GraphQLError } from "graphql" ;
2830
2931interface IAtlasProvider {
3032 isVerified : boolean ;
@@ -94,16 +96,30 @@ const AtlasProvider: React.FC<{ children?: React.ReactNode }> = ({ children }) =
9496 } , [ authToken , address ] ) ;
9597
9698 useEffect ( ( ) => {
97- // initial verfiy check
98- setIsVerified ( verifySession ( ) ) ;
99+ let timeoutId : ReturnType < typeof setTimeout > ;
100+
101+ const verifyAndSchedule = ( ) => {
102+ // initial verify check
103+ const isValid = verifySession ( ) ;
104+ setIsVerified ( isValid ) ;
105+
106+ if ( isValid && authToken ) {
107+ try {
108+ const payload = decodeJwt ( authToken ) ;
109+ const expiresIn = ( payload . exp as number ) * 1000 - Date . now ( ) ;
110+
111+ timeoutId = setTimeout ( verifyAndSchedule , Math . max ( 0 , expiresIn ) ) ;
112+ } catch ( err ) {
113+ console . error ( "Error decoding JWT:" , err ) ;
114+ setIsVerified ( false ) ;
115+ }
116+ }
117+ } ;
99118
100- // verify session every 5 sec
101- const intervalId = setInterval ( ( ) => {
102- setIsVerified ( verifySession ( ) ) ;
103- } , 5000 ) ;
119+ verifyAndSchedule ( ) ;
104120
105121 return ( ) => {
106- clearInterval ( intervalId ) ;
122+ clearTimeout ( timeoutId ) ;
107123 } ;
108124 } , [ authToken , verifySession , address ] ) ;
109125
@@ -140,6 +156,20 @@ const AtlasProvider: React.FC<{ children?: React.ReactNode }> = ({ children }) =
140156 return ! isUndefined ( user . email ) ;
141157 } , [ user ] ) ;
142158
159+ async function fetchWithAuthErrorHandling < T > ( request : ( ) => Promise < T > ) : Promise < T > {
160+ try {
161+ return await request ( ) ;
162+ } catch ( error ) {
163+ if (
164+ error instanceof AuthorizationError ||
165+ ( error instanceof GraphQLError && error ?. extensions ?. [ "code" ] === "UNAUTHENTICATED" )
166+ ) {
167+ setIsVerified ( false ) ;
168+ }
169+ throw error ;
170+ }
171+ }
172+
143173 /**
144174 * @description authorise user and enable authorised calls
145175 */
@@ -173,7 +203,7 @@ const AtlasProvider: React.FC<{ children?: React.ReactNode }> = ({ children }) =
173203 if ( ! address || ! isVerified ) return false ;
174204 setIsAddingUser ( true ) ;
175205
176- const userAdded = await addUserToAtlas ( atlasGqlClient , userSettings ) ;
206+ const userAdded = await fetchWithAuthErrorHandling ( ( ) => addUserToAtlas ( atlasGqlClient , userSettings ) ) ;
177207 refetchUser ( ) ;
178208
179209 return userAdded ;
@@ -199,7 +229,7 @@ const AtlasProvider: React.FC<{ children?: React.ReactNode }> = ({ children }) =
199229 if ( ! address || ! isVerified ) return false ;
200230 setIsUpdatingUser ( true ) ;
201231
202- const emailUpdated = await updateEmailInAtlas ( atlasGqlClient , userSettings ) ;
232+ const emailUpdated = await fetchWithAuthErrorHandling ( ( ) => updateEmailInAtlas ( atlasGqlClient , userSettings ) ) ;
203233 refetchUser ( ) ;
204234
205235 return emailUpdated ;
@@ -227,9 +257,8 @@ const AtlasProvider: React.FC<{ children?: React.ReactNode }> = ({ children }) =
227257 if ( ! address || ! isVerified || ! atlasUri || ! authToken ) return null ;
228258 setIsUploadingFile ( true ) ;
229259
230- const hash = await uploadToIpfs (
231- { baseUrl : atlasUri , authToken } ,
232- { file, name : file . name , role, product : Products . CourtV2 }
260+ const hash = await fetchWithAuthErrorHandling ( ( ) =>
261+ uploadToIpfs ( { baseUrl : atlasUri , authToken } , { file, name : file . name , role, product : Products . CourtV2 } )
233262 ) ;
234263 return hash ? `/ipfs/${ hash } ` : null ;
235264 } catch ( err : any ) {
0 commit comments