Skip to content

Commit 778cc60

Browse files
committed
refresh token immediately if instantiated with invalid token
1 parent 5223eec commit 778cc60

File tree

1 file changed

+36
-20
lines changed

1 file changed

+36
-20
lines changed

src/commonMain/kotlin/com.adamratzman.spotify/SpotifyApi.kt

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import com.adamratzman.spotify.models.serialization.toObject
2929
import com.adamratzman.spotify.utils.asList
3030
import com.adamratzman.spotify.utils.runBlocking
3131
import kotlinx.coroutines.Dispatchers
32+
import kotlinx.serialization.json.Json
3233
import kotlin.coroutines.CoroutineContext
3334
import kotlin.jvm.JvmOverloads
3435

@@ -64,7 +65,8 @@ sealed class SpotifyApi<T : SpotifyApi<T, B>, B : ISpotifyApiBuilder<T, B>>(
6465
var automaticRefresh: Boolean,
6566
var retryWhenRateLimited: Boolean,
6667
enableLogger: Boolean,
67-
testTokenValidity: Boolean
68+
testTokenValidity: Boolean,
69+
var json: Json
6870
) {
6971
var useCache = useCache
7072
set(value) {
@@ -87,11 +89,15 @@ sealed class SpotifyApi<T : SpotifyApi<T, B>, B : ISpotifyApiBuilder<T, B>>(
8789

8890
init {
8991
if (testTokenValidity) {
90-
try {
91-
isTokenValid(true)
92-
} catch (e: Exception) {
93-
throw SpotifyAuthenticationException("Invalid token provided on initialization", e)
94-
}
92+
if (!isTokenValid().isValid)
93+
try {
94+
refreshToken()
95+
} catch (e: SpotifyException.BadRequestException) {
96+
throw SpotifyException.AuthenticationException(
97+
"Invalid token and refresh token supplied. Cannot refresh to a fresh token.",
98+
e
99+
)
100+
}
95101
}
96102
}
97103

@@ -172,10 +178,13 @@ sealed class SpotifyApi<T : SpotifyApi<T, B>, B : ISpotifyApiBuilder<T, B>>(
172178
}
173179

174180
@JvmOverloads
175-
suspend fun suspendIsTokenValid(makeTestRequest: Boolean = true, context: CoroutineContext = Dispatchers.Default): TokenValidityResponse {
181+
suspend fun suspendIsTokenValid(
182+
makeTestRequest: Boolean = true,
183+
context: CoroutineContext = Dispatchers.Default
184+
): TokenValidityResponse {
176185
if (token.shouldRefresh()) return TokenValidityResponse(
177186
false,
178-
SpotifyAuthenticationException("Token needs to be refreshed (is it expired?)")
187+
SpotifyException.AuthenticationException("Token needs to be refreshed (is it expired?)")
179188
)
180189
if (!makeTestRequest) return TokenValidityResponse(true, null)
181190

@@ -210,7 +219,8 @@ class SpotifyAppApi internal constructor(
210219
automaticRefresh: Boolean,
211220
retryWhenRateLimited: Boolean,
212221
enableLogger: Boolean,
213-
testTokenValidity: Boolean
222+
testTokenValidity: Boolean,
223+
json: Json
214224
) : SpotifyApi<SpotifyAppApi, SpotifyAppApiBuilder>(
215225
clientId,
216226
clientSecret,
@@ -220,7 +230,8 @@ class SpotifyAppApi internal constructor(
220230
automaticRefresh,
221231
retryWhenRateLimited,
222232
enableLogger,
223-
testTokenValidity
233+
testTokenValidity,
234+
json
224235
) {
225236
constructor(
226237
clientId: String,
@@ -236,7 +247,8 @@ class SpotifyAppApi internal constructor(
236247
options.automaticRefresh,
237248
options.retryWhenRateLimited,
238249
options.enableLogger,
239-
options.testTokenValidity
250+
options.testTokenValidity,
251+
options.json
240252
)
241253

242254
override val search: SearchApi = SearchApi(this)
@@ -264,7 +276,7 @@ class SpotifyAppApi internal constructor(
264276
require(clientId != null && clientSecret != null) { "Either the client id or the client secret is not set" }
265277
val currentToken = this.token
266278

267-
token = getCredentialedToken(clientId, clientSecret, this)
279+
token = getCredentialedToken(clientId, clientSecret, this, json)
268280

269281
return currentToken
270282
}
@@ -311,7 +323,8 @@ class SpotifyClientApi internal constructor(
311323
automaticRefresh: Boolean,
312324
retryWhenRateLimited: Boolean,
313325
enableLogger: Boolean,
314-
testTokenValidity: Boolean
326+
testTokenValidity: Boolean,
327+
json: Json
315328
) : SpotifyApi<SpotifyClientApi, SpotifyClientApiBuilder>(
316329
clientId,
317330
clientSecret,
@@ -321,7 +334,8 @@ class SpotifyClientApi internal constructor(
321334
automaticRefresh,
322335
retryWhenRateLimited,
323336
enableLogger,
324-
testTokenValidity
337+
testTokenValidity,
338+
json
325339
) {
326340
constructor(
327341
clientId: String,
@@ -339,7 +353,8 @@ class SpotifyClientApi internal constructor(
339353
options.automaticRefresh,
340354
options.retryWhenRateLimited,
341355
options.enableLogger,
342-
options.testTokenValidity
356+
options.testTokenValidity,
357+
options.json
343358
)
344359

345360
override val search: SearchApi = SearchApi(this)
@@ -431,7 +446,7 @@ class SpotifyClientApi internal constructor(
431446
)
432447

433448
if (response.responseCode / 200 == 1) {
434-
val tempToken = response.body.toObject(Token.serializer(), this)
449+
val tempToken = response.body.toObject(Token.serializer(), this, json)
435450
this.token = tempToken.copy(
436451
refreshToken = tempToken.refreshToken ?: this.token.refreshToken
437452
).apply { scopes = tempToken.scopes }
@@ -441,7 +456,8 @@ class SpotifyClientApi internal constructor(
441456
} else throw SpotifyException.BadRequestException(
442457
response.body.toObject(
443458
AuthenticationError.serializer(),
444-
this
459+
this,
460+
json
445461
)
446462
)
447463
}
@@ -520,7 +536,7 @@ fun getAuthUrlFull(vararg scopes: SpotifyScope, clientId: String, redirectUri: S
520536
if (scopes.isEmpty()) "" else "&scope=${scopes.joinToString("%20") { it.uri }}"
521537
}
522538

523-
suspend fun getCredentialedToken(clientId: String, clientSecret: String, api: SpotifyApi<*, *>?): Token {
539+
suspend fun getCredentialedToken(clientId: String, clientSecret: String, api: SpotifyApi<*, *>?, json: Json): Token {
524540
val response = executeTokenRequest(
525541
HttpConnection(
526542
"https://accounts.spotify.com/api/token",
@@ -533,9 +549,9 @@ suspend fun getCredentialedToken(clientId: String, clientSecret: String, api: Sp
533549
), clientId, clientSecret
534550
)
535551

536-
if (response.responseCode / 200 == 1) return response.body.toObject(Token.serializer(), null)
552+
if (response.responseCode / 200 == 1) return response.body.toObject(Token.serializer(), null, json)
537553

538-
throw SpotifyException.BadRequestException(response.body.toObject(AuthenticationError.serializer(), null))
554+
throw SpotifyException.BadRequestException(response.body.toObject(AuthenticationError.serializer(), null, json))
539555
}
540556

541557
internal suspend fun executeTokenRequest(

0 commit comments

Comments
 (0)