Skip to content

Commit 9b0fa7b

Browse files
committed
1. Add logic to customise JWT
2. Add logic to refresh JWT for CoordinatorSocket
1 parent a0e6443 commit 9b0fa7b

File tree

5 files changed

+50
-8
lines changed

5 files changed

+50
-8
lines changed

demo-app/src/main/kotlin/io/getstream/video/android/data/services/stream/StreamService.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,12 @@ fun interface StreamService {
3232
suspend fun getAuthData(
3333
@Query("environment") environment: String,
3434
@Query("user_id") userId: String?,
35+
@Query("exp") exp: Int,
3536
): GetAuthDataResponse
3637

3738
companion object {
3839
private const val BASE_URL = "https://pronto.getstream.io/"
39-
40+
public const val TOKEN_EXPIRY_TIME = 40
4041
private val json = Json { ignoreUnknownKeys = true }
4142

4243
private val retrofit = Retrofit.Builder()
@@ -46,9 +47,9 @@ fun interface StreamService {
4647

4748
private val serviceInstance = retrofit.create<StreamService>()
4849

49-
val instance = StreamService { environment, userId ->
50+
val instance = StreamService { environment, userId, exp ->
5051
User.builtInCredentials[userId]?.toAuthDataResponse()
51-
?: serviceInstance.getAuthData(environment, userId)
52+
?: serviceInstance.getAuthData(environment, userId, exp)
5253
}
5354
}
5455
}

demo-app/src/main/kotlin/io/getstream/video/android/ui/login/LoginViewModel.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ class LoginViewModel @Inject constructor(
9292
val authData = StreamService.instance.getAuthData(
9393
environment = it.env,
9494
userId = userId,
95+
StreamService.TOKEN_EXPIRY_TIME,
9596
)
9697
val loggedInGoogleUser =
9798
if (autoLogIn) null else googleAccountRepository.getCurrentUser()
@@ -128,6 +129,7 @@ class LoginViewModel @Inject constructor(
128129
val authData = StreamService.instance.getAuthData(
129130
environment = it.env,
130131
userId = user.id,
132+
StreamService.TOKEN_EXPIRY_TIME,
131133
)
132134
// Store the data in the demo app
133135
dataStore.updateUser(user)

demo-app/src/main/kotlin/io/getstream/video/android/util/StreamVideoInitHelper.kt

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ import io.getstream.video.android.util.config.AppConfig
5858
import kotlinx.coroutines.flow.MutableStateFlow
5959
import kotlinx.coroutines.flow.StateFlow
6060
import kotlinx.coroutines.flow.firstOrNull
61+
import kotlinx.coroutines.runBlocking
6162

6263
public enum class InitializedState {
6364
NOT_STARTED, RUNNING, FINISHED, FAILED
@@ -121,6 +122,7 @@ object StreamVideoInitHelper {
121122
authData = StreamService.instance.getAuthData(
122123
environment = AppConfig.currentEnvironment.value!!.env,
123124
userId = userId,
125+
StreamService.TOKEN_EXPIRY_TIME,
124126
)
125127

126128
loggedInUser = User(id = authData.userId, role = "admin")
@@ -137,6 +139,7 @@ object StreamVideoInitHelper {
137139
authData = StreamService.instance.getAuthData(
138140
environment = AppConfig.currentEnvironment.value!!.env,
139141
userId = loggedInUser.id,
142+
StreamService.TOKEN_EXPIRY_TIME,
140143
)
141144
}
142145

@@ -194,7 +197,24 @@ object StreamVideoInitHelper {
194197

195198
chatClient.connectUser(
196199
user = chatUser,
197-
token = token,
200+
tokenProvider = object : io.getstream.chat.android.client.token.TokenProvider {
201+
override fun loadToken(): String {
202+
return runBlocking {
203+
Log.d("TokenProvider", "[loadToken] Chat token provider START")
204+
val email = user.custom?.get("email")
205+
val authData = StreamService.instance.getAuthData(
206+
environment = AppConfig.currentEnvironment.value!!.env,
207+
userId = email,
208+
StreamService.TOKEN_EXPIRY_TIME,
209+
)
210+
Log.d(
211+
"TokenProvider",
212+
"[loadToken] Chat token provider END, token: ${authData.token}",
213+
)
214+
authData.token
215+
}
216+
}
217+
},
198218
).enqueue()
199219
}
200220

@@ -286,10 +306,18 @@ object StreamVideoInitHelper {
286306
),
287307
tokenProvider = object : TokenProvider {
288308
override suspend fun loadToken(): String {
289-
val email = user.custom?.get("email")
309+
val userEmail = user.custom?.get("email")
310+
val userId = user.id
311+
val userIdForTokenRenewal = if (userEmail.isNullOrEmpty()) userId else userEmail
312+
Log.d("TokenProvider", "[loadToken] Video token provider START")
290313
val authData = StreamService.instance.getAuthData(
291314
environment = AppConfig.currentEnvironment.value!!.env,
292-
userId = email,
315+
userId = userIdForTokenRenewal,
316+
StreamService.TOKEN_EXPIRY_TIME,
317+
)
318+
Log.d(
319+
"TokenProvider",
320+
"[loadToken] Video token provider END: ${authData.token}",
293321
)
294322
return authData.token
295323
}

stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/socket/coordinator/CoordinatorSocket.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,15 @@ internal open class CoordinatorSocket(
278278
tokenManager.expireToken()
279279
}
280280

281+
if (error.serverErrorCode == VideoErrorCode.TOKEN_EXPIRED.code) {
282+
logger.d { "[onVideoNetworkError] load sync START" }
283+
tokenManager.expireToken()
284+
val token = tokenManager.loadSync()
285+
if (token.isNotEmpty()) {
286+
logger.d { "[onVideoNetworkError] load sync END: $token" }
287+
}
288+
}
289+
281290
when (error.serverErrorCode) {
282291
VideoErrorCode.UNDEFINED_TOKEN.code,
283292
VideoErrorCode.INVALID_TOKEN.code,

stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/socket/coordinator/CoordinatorSocketConnection.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,17 @@ public open class CoordinatorSocketConnection(
126126
// Extension opportunity for subclasses
127127
override fun onCreated() {
128128
super.onCreated()
129-
logger.d { "[onCreated] Socket is created" }
129+
logger.d {
130+
"[onCreated] Socket is created, initial token: $token, tokenManager.getToken() = ${tokenManager.getToken()}"
131+
}
130132
scope.launch {
131133
logger.d { "[onConnected] Video socket created, user: $user" }
132134
if (token.isEmpty()) {
133135
logger.e { "[onConnected] Token is empty. Disconnecting." }
134136
disconnect()
135137
} else {
136138
val authRequest = WSAuthMessageRequest(
137-
token = token,
139+
token = tokenManager.getToken().ifEmpty { token },
138140
userDetails = ConnectUserDetailsRequest(
139141
id = user.id,
140142
name = user.name.takeUnless { it.isWhitespaceOnly() },

0 commit comments

Comments
 (0)