1
1
import { apiPrefix } from '@/config'
2
2
import { fetchWithRetry } from '@/utils'
3
3
4
+ const LOCAL_STORAGE_KEY = 'is_other_tab_refreshing'
5
+
4
6
let isRefreshing = false
5
7
function waitUntilTokenRefreshed ( ) {
6
8
return new Promise < void > ( ( resolve , reject ) => {
7
9
function _check ( ) {
8
- const isRefreshingSign = localStorage . getItem ( 'is_refreshing' )
10
+ const isRefreshingSign = globalThis . localStorage . getItem ( LOCAL_STORAGE_KEY )
9
11
if ( ( isRefreshingSign && isRefreshingSign === '1' ) || isRefreshing ) {
10
12
setTimeout ( ( ) => {
11
13
_check ( )
@@ -22,13 +24,14 @@ function waitUntilTokenRefreshed() {
22
24
// only one request can send
23
25
async function getNewAccessToken ( ) : Promise < void > {
24
26
try {
25
- const isRefreshingSign = localStorage . getItem ( 'is_refreshing' )
27
+ const isRefreshingSign = globalThis . localStorage . getItem ( LOCAL_STORAGE_KEY )
26
28
if ( ( isRefreshingSign && isRefreshingSign === '1' ) || isRefreshing ) {
27
29
await waitUntilTokenRefreshed ( )
28
30
}
29
31
else {
30
- globalThis . localStorage . setItem ( 'is_refreshing' , '1' )
31
32
isRefreshing = true
33
+ globalThis . localStorage . setItem ( LOCAL_STORAGE_KEY , '1' )
34
+ globalThis . addEventListener ( 'beforeunload' , releaseRefreshLock )
32
35
const refresh_token = globalThis . localStorage . getItem ( 'refresh_token' )
33
36
34
37
// Do not use baseFetch to refresh tokens.
@@ -61,15 +64,21 @@ async function getNewAccessToken(): Promise<void> {
61
64
return Promise . reject ( error )
62
65
}
63
66
finally {
67
+ releaseRefreshLock ( )
68
+ }
69
+ }
70
+
71
+ function releaseRefreshLock ( ) {
72
+ if ( isRefreshing ) {
64
73
isRefreshing = false
65
- globalThis . localStorage . removeItem ( 'is_refreshing' )
74
+ globalThis . localStorage . removeItem ( LOCAL_STORAGE_KEY )
75
+ globalThis . removeEventListener ( 'beforeunload' , releaseRefreshLock )
66
76
}
67
77
}
68
78
69
79
export async function refreshAccessTokenOrRelogin ( timeout : number ) {
70
80
return Promise . race ( [ new Promise < void > ( ( resolve , reject ) => setTimeout ( ( ) => {
71
- isRefreshing = false
72
- globalThis . localStorage . removeItem ( 'is_refreshing' )
81
+ releaseRefreshLock ( )
73
82
reject ( new Error ( 'request timeout' ) )
74
83
} , timeout ) ) , getNewAccessToken ( ) ] )
75
84
}
0 commit comments