feat(android): serialize rotating mobile refresh tokens
This commit is contained in:
@@ -0,0 +1,32 @@
|
|||||||
|
package com.korexlabs.dhinspeccion.data
|
||||||
|
|
||||||
|
import kotlinx.coroutines.sync.Mutex
|
||||||
|
import kotlinx.coroutines.sync.withLock
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializa la rotación del refresh token a nivel de proceso.
|
||||||
|
*
|
||||||
|
* El backend rota el token en cada refresh. Si dos repositorios reciben 401 al mismo tiempo,
|
||||||
|
* sólo el primero debe consumir el token anterior; el segundo reutiliza la sesión ya renovada.
|
||||||
|
*/
|
||||||
|
class SessionRefreshGate {
|
||||||
|
private val mutex = Mutex()
|
||||||
|
|
||||||
|
suspend fun refreshIfNeeded(
|
||||||
|
previousRefreshToken: String,
|
||||||
|
load: () -> StoredSession?,
|
||||||
|
save: (MobileSessionResponse) -> StoredSession,
|
||||||
|
clear: () -> Unit,
|
||||||
|
refresh: suspend (String) -> MobileSessionResponse,
|
||||||
|
): StoredSession = mutex.withLock {
|
||||||
|
val latest = load() ?: throw IllegalStateException("Sesión no iniciada")
|
||||||
|
if (latest.refreshToken != previousRefreshToken) return@withLock latest
|
||||||
|
|
||||||
|
try {
|
||||||
|
save(refresh(previousRefreshToken))
|
||||||
|
} catch (error: Throwable) {
|
||||||
|
clear()
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user