1
1
import React , { createContext , useContext , useState , useEffect } from "react" ;
2
+ import { handleUnauthorized } from "../utils/auth" ;
2
3
3
4
interface AuthContextType {
4
5
token : string | null ;
5
6
setToken : ( token : string | null ) => void ;
6
7
isAuthenticated : boolean ;
8
+ isLoading : boolean ;
7
9
}
8
10
9
11
export const AuthContext = createContext < AuthContextType | undefined > ( undefined ) ;
@@ -20,6 +22,7 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
20
22
const [ token , setTokenState ] = useState < string | null > ( ( ) => {
21
23
return localStorage . getItem ( "auth" ) ;
22
24
} ) ;
25
+ const [ isLoading , setIsLoading ] = useState ( true ) ;
23
26
24
27
const setToken = ( newToken : string | null ) => {
25
28
if ( newToken ) {
@@ -30,6 +33,38 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
30
33
setTokenState ( newToken ) ;
31
34
} ;
32
35
36
+ // Check token validity on mount and when token changes
37
+ useEffect ( ( ) => {
38
+ if ( token ) {
39
+ // Make a request to any authenticated endpoint to check token validity
40
+ fetch ( "/api/install/installation/config" , {
41
+ headers : {
42
+ Authorization : `Bearer ${ token } ` ,
43
+ } ,
44
+ } )
45
+ . then ( ( response ) => {
46
+ if ( ! response . ok ) {
47
+ // If we get a 401, handle it
48
+ if ( response . status === 401 ) {
49
+ const error = new Error ( "Unauthorized" ) ;
50
+ ( error as Error & { status ?: number } ) . status = 401 ;
51
+ handleUnauthorized ( error ) ;
52
+ }
53
+ }
54
+ setIsLoading ( false ) ;
55
+ } )
56
+ . catch ( ( ) => {
57
+ // If the request fails, assume the token is invalid
58
+ const err = new Error ( "Request failed" ) ;
59
+ ( err as Error & { status ?: number } ) . status = 401 ;
60
+ handleUnauthorized ( err ) ;
61
+ setIsLoading ( false ) ;
62
+ } ) ;
63
+ } else {
64
+ setIsLoading ( false ) ;
65
+ }
66
+ } , [ token ] ) ;
67
+
33
68
useEffect ( ( ) => {
34
69
// Listen for storage events to sync token state across tabs
35
70
const handleStorageChange = ( e : StorageEvent ) => {
@@ -48,7 +83,12 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
48
83
token,
49
84
setToken,
50
85
isAuthenticated : ! ! token ,
86
+ isLoading,
51
87
} ;
52
88
89
+ if ( isLoading ) {
90
+ return null ; // Don't render anything while checking token validity
91
+ }
92
+
53
93
return < AuthContext . Provider value = { value } > { children } </ AuthContext . Provider > ;
54
94
} ;
0 commit comments