44package com.adamratzman.spotify
55
66import com.adamratzman.spotify.SpotifyException.BadRequestException
7- import com.adamratzman.spotify.endpoints.client.ClientEpisodeApi
8- import com.adamratzman.spotify.endpoints.client.ClientFollowingApi
9- import com.adamratzman.spotify.endpoints.client.ClientLibraryApi
10- import com.adamratzman.spotify.endpoints.client.ClientPersonalizationApi
11- import com.adamratzman.spotify.endpoints.client.ClientPlayerApi
12- import com.adamratzman.spotify.endpoints.client.ClientPlaylistApi
13- import com.adamratzman.spotify.endpoints.client.ClientProfileApi
14- import com.adamratzman.spotify.endpoints.client.ClientShowApi
15- import com.adamratzman.spotify.endpoints.pub.AlbumApi
16- import com.adamratzman.spotify.endpoints.pub.ArtistApi
17- import com.adamratzman.spotify.endpoints.pub.BrowseApi
18- import com.adamratzman.spotify.endpoints.pub.EpisodeApi
19- import com.adamratzman.spotify.endpoints.pub.FollowingApi
20- import com.adamratzman.spotify.endpoints.pub.MarketsApi
21- import com.adamratzman.spotify.endpoints.pub.PlaylistApi
22- import com.adamratzman.spotify.endpoints.pub.SearchApi
23- import com.adamratzman.spotify.endpoints.pub.ShowApi
24- import com.adamratzman.spotify.endpoints.pub.TrackApi
25- import com.adamratzman.spotify.endpoints.pub.UserApi
26- import com.adamratzman.spotify.http.CacheState
27- import com.adamratzman.spotify.http.HttpHeader
28- import com.adamratzman.spotify.http.HttpRequest
29- import com.adamratzman.spotify.http.HttpRequestMethod
30- import com.adamratzman.spotify.http.HttpResponse
31- import com.adamratzman.spotify.http.SpotifyEndpoint
32- import com.adamratzman.spotify.http.SpotifyRequest
7+ import com.adamratzman.spotify.endpoints.client.*
8+ import com.adamratzman.spotify.endpoints.pub.*
9+ import com.adamratzman.spotify.http.*
3310import com.adamratzman.spotify.models.AuthenticationError
3411import com.adamratzman.spotify.models.Token
3512import com.adamratzman.spotify.models.TokenValidityResponse
@@ -238,12 +215,20 @@ public sealed class SpotifyApi<T : SpotifyApi<T, B>, B : ISpotifyApiBuilder<T, B
238215 * @throws BadRequestException if refresh fails
239216 * @throws IllegalStateException if [SpotifyApiOptions.refreshTokenProducer] is null
240217 */
241- public suspend fun refreshToken (): Token = spotifyApiOptions.refreshTokenProducer?.invoke(this )?.apply {
242- this @SpotifyApi.token = this
218+ public suspend fun refreshToken (): Token {
219+ val oldToken = token
220+ val refreshedToken = spotifyApiOptions.refreshTokenProducer?.invoke(this )
221+ ? : throw SpotifyException .ReAuthenticationNeededException (IllegalStateException (" The refreshTokenProducer is null." ))
222+
223+ token = refreshedToken
224+ // Spotify may not provide a new refresh token
225+ if (token.refreshToken == null ) token.refreshToken = oldToken.refreshToken
226+
243227 spotifyApiOptions.onTokenRefresh?.invoke(this @SpotifyApi)
244228 spotifyApiOptions.afterTokenRefresh?.invoke(this @SpotifyApi)
229+
230+ return oldToken
245231 }
246- ? : throw SpotifyException .ReAuthenticationNeededException (IllegalStateException (" The refreshTokenProducer is null." ))
247232
248233 /* *
249234 * If the method used to create the [token] supports token refresh and
@@ -291,15 +276,15 @@ public sealed class SpotifyApi<T : SpotifyApi<T, B>, B : ISpotifyApiBuilder<T, B
291276 state : String? = null
292277 ): String {
293278 return " https://accounts.spotify.com/authorize/?client_id=$clientId " +
294- " &response_type=${if (isImplicitGrantFlow) " token" else " code" } " +
295- " &redirect_uri=$redirectUri " +
296- (state?.let { " &state=$it " } ? : " " ) +
297- if (scopes.isEmpty()) {
298- " "
299- } else {
300- " &scope=${scopes.joinToString(" %20" ) { it.uri }} " +
301- if (shouldShowDialog) " &show_dialog=$shouldShowDialog " else " "
302- }
279+ " &response_type=${if (isImplicitGrantFlow) " token" else " code" } " +
280+ " &redirect_uri=$redirectUri " +
281+ (state?.let { " &state=$it " } ? : " " ) +
282+ if (scopes.isEmpty()) {
283+ " "
284+ } else {
285+ " &scope=${scopes.joinToString(" %20" ) { it.uri }} " +
286+ if (shouldShowDialog) " &show_dialog=$shouldShowDialog " else " "
287+ }
303288 }
304289
305290 /* *
@@ -321,12 +306,12 @@ public sealed class SpotifyApi<T : SpotifyApi<T, B>, B : ISpotifyApiBuilder<T, B
321306 state : String? = null
322307 ): String {
323308 return " https://accounts.spotify.com/authorize/?client_id=$clientId " +
324- " &response_type=code" +
325- " &redirect_uri=$redirectUri " +
326- " &code_challenge_method=S256" +
327- " &code_challenge=$codeChallenge " +
328- (state?.let { " &state=$it " } ? : " " ) +
329- if (scopes.isEmpty()) " " else " &scope=${scopes.joinToString(" %20" ) { it.uri }} "
309+ " &response_type=code" +
310+ " &redirect_uri=$redirectUri " +
311+ " &code_challenge_method=S256" +
312+ " &code_challenge=$codeChallenge " +
313+ (state?.let { " &state=$it " } ? : " " ) +
314+ if (scopes.isEmpty()) " " else " &scope=${scopes.joinToString(" %20" ) { it.uri }} "
330315 }
331316
332317 /* *
@@ -645,8 +630,8 @@ public open class SpotifyClientApi(
645630 null
646631 } else {
647632 isTokenValid(false ).isValid &&
648- token.scopes?.contains(scope) == true &&
649- scopes.all { token.scopes?.contains(it) == true }
633+ token.scopes?.contains(scope) == true &&
634+ scopes.all { token.scopes?.contains(it) == true }
650635 }
651636
652637 /* *
0 commit comments