@dpgradio/creative 8.0.0 → 8.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package-lock.json +8362 -0
- package/package.json +1 -1
- package/src/api/request.js +21 -0
- package/src/app/authentication.js +40 -5
package/package.json
CHANGED
package/src/api/request.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import tap from '../utils/tap.js'
|
|
2
|
+
import authentication from '../app/authentication.js'
|
|
2
3
|
|
|
4
|
+
let authenticationRetries = 0
|
|
5
|
+
let tokenRefreshPromise = null
|
|
3
6
|
export default class Request {
|
|
4
7
|
constructor(baseUrl, version, errorHandlers = []) {
|
|
5
8
|
this.baseUrl = baseUrl
|
|
@@ -76,6 +79,21 @@ export default class Request {
|
|
|
76
79
|
})
|
|
77
80
|
|
|
78
81
|
if (!response.ok) {
|
|
82
|
+
if (response.status === 401 && authenticationRetries < 2) {
|
|
83
|
+
if (!tokenRefreshPromise) {
|
|
84
|
+
tokenRefreshPromise = authentication.refreshToken()
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
const newToken = await tokenRefreshPromise
|
|
89
|
+
authenticationRetries++
|
|
90
|
+
this.withHeader('Authorization', `Bearer ${newToken}`)
|
|
91
|
+
return await this.fetchJson(endpoint, method)
|
|
92
|
+
} finally {
|
|
93
|
+
tokenRefreshPromise = null
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
79
97
|
this.errorHandlers.forEach((handler) => handler({ response }))
|
|
80
98
|
|
|
81
99
|
throw new Error(
|
|
@@ -84,6 +102,9 @@ export default class Request {
|
|
|
84
102
|
)
|
|
85
103
|
}
|
|
86
104
|
|
|
105
|
+
// reset authentication retries
|
|
106
|
+
authenticationRetries = 0
|
|
107
|
+
|
|
87
108
|
try {
|
|
88
109
|
return await response.json()
|
|
89
110
|
} catch (error) {
|
|
@@ -22,11 +22,14 @@ class Authentication {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
initialize() {
|
|
25
|
-
hybrid
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
hybrid
|
|
26
|
+
.appLoaded()
|
|
27
|
+
.then((radioToken) => {
|
|
28
|
+
if (radioToken) {
|
|
29
|
+
this.setToken(radioToken)
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
.catch(() => {}) // We don't have to do anything if there is no radio token at app load
|
|
30
33
|
hybrid.on('authenticated', ({ radioToken }) => {
|
|
31
34
|
this.setToken(radioToken)
|
|
32
35
|
})
|
|
@@ -110,6 +113,38 @@ class Authentication {
|
|
|
110
113
|
}
|
|
111
114
|
})
|
|
112
115
|
}
|
|
116
|
+
|
|
117
|
+
async refreshToken() {
|
|
118
|
+
if (hybrid.isNativeApp()) {
|
|
119
|
+
const updatedToken = Promise.race([
|
|
120
|
+
new Promise((resolve) => {
|
|
121
|
+
hybrid.on('authenticated', (token) => resolve(token))
|
|
122
|
+
}),
|
|
123
|
+
new Promise((_, reject) => {
|
|
124
|
+
setTimeout(() => reject(new Error('Timeout: no token received')), 2000)
|
|
125
|
+
}),
|
|
126
|
+
])
|
|
127
|
+
|
|
128
|
+
hybrid.call('refreshExpiredToken')
|
|
129
|
+
|
|
130
|
+
return (await updatedToken).radioToken
|
|
131
|
+
} else {
|
|
132
|
+
try {
|
|
133
|
+
const response = await fetch('/login/refresh', {
|
|
134
|
+
method: 'POST',
|
|
135
|
+
headers: {
|
|
136
|
+
'Content-Type': 'application/json',
|
|
137
|
+
},
|
|
138
|
+
})
|
|
139
|
+
const token = (await response.json()).radioToken
|
|
140
|
+
localStorage.setItem(RADIO_TOKEN_LOCAL_STORAGE_KEY, token)
|
|
141
|
+
return token
|
|
142
|
+
} catch (e) {
|
|
143
|
+
localStorage.removeItem(RADIO_TOKEN_LOCAL_STORAGE_KEY)
|
|
144
|
+
throw e
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
113
148
|
}
|
|
114
149
|
|
|
115
150
|
export default new Authentication()
|