@@ -132,25 +132,40 @@ internal class BackendClientDemo internal constructor(
132
132
* because the new one is tied to client and has more permissions.
133
133
* Not needed in the actual implementation, as the SDK is authenticated with the API_TOKEN
134
134
*/
135
- private suspend fun loginUser (): String {
136
- if (cachedAccessToken != null ) return cachedAccessToken as String
135
+ private var tokenTimestamp: Long? = null
137
136
138
- val loginResponse = httpClient.post(" /$API_VERSION /login" ) {
139
- setBody(LoginRequest (DEMO_USER_EMAIL , DEMO_USER_PASSWORD ))
140
- contentType(ContentType .Application .Json )
137
+ private suspend fun loginUser (): String {
138
+ val currentTime = System .currentTimeMillis()
139
+
140
+ // Check if token is valid (not null and not expired)
141
+ if (cachedAccessToken != null && tokenTimestamp != null ) {
142
+ val timeSinceTokenIssued = currentTime - tokenTimestamp!!
143
+ if (timeSinceTokenIssued < TOKEN_EXPIRATION_MS ) {
144
+ return cachedAccessToken as String
141
145
}
142
- val zuidCookie = loginResponse.setCookie()[" zuid" ]
146
+ // Token has expired, will get a new one
147
+ logger.info(" Access token expired, getting a new one" )
148
+ }
143
149
144
- val accessResponse =
145
- httpClient.post(" /$API_VERSION /access?client_id=$DEMO_USER_CLIENT " ) {
146
- headers {
147
- append(HttpHeaders .Cookie , " zuid=${zuidCookie!! .value} " )
148
- }
149
- accept(ContentType .Application .Json )
150
- }.body<LoginResponse >()
151
- cachedAccessToken = accessResponse.accessToken
152
- return accessResponse.accessToken
150
+ val loginResponse = httpClient.post(" /$API_VERSION /login" ) {
151
+ setBody(LoginRequest (DEMO_USER_EMAIL , DEMO_USER_PASSWORD ))
152
+ contentType(ContentType .Application .Json )
153
153
}
154
+ val zuidCookie = loginResponse.setCookie()[" zuid" ]
155
+
156
+ val accessResponse =
157
+ httpClient.post(" /$API_VERSION /access?client_id=$DEMO_USER_CLIENT " ) {
158
+ headers {
159
+ append(HttpHeaders .Cookie , " zuid=${zuidCookie!! .value} " )
160
+ }
161
+ accept(ContentType .Application .Json )
162
+ }.body<LoginResponse >()
163
+
164
+ cachedAccessToken = accessResponse.accessToken
165
+ tokenTimestamp = currentTime
166
+
167
+ return accessResponse.accessToken
168
+ }
154
169
155
170
override suspend fun updateClientWithMlsPublicKey (
156
171
appClientId : AppClientId ,
@@ -338,6 +353,7 @@ internal class BackendClientDemo internal constructor(
338
353
const val PATH_PUBLIC_ASSETS_V3 = " assets/v3"
339
354
const val PATH_PUBLIC_ASSETS_V4 = " assets/v4"
340
355
const val HEADER_ASSET_TOKEN = " Asset-Token"
356
+ const val TOKEN_EXPIRATION_MS = 14 * 60 * 1000 // 14 minutes in milliseconds
341
357
342
358
val DEMO_USER_EMAIL : String by lazy {
343
359
DemoProperties .properties.getProperty(
0 commit comments