Skip to content

Commit d5f52d8

Browse files
authored
Merge pull request #330 from BobbyESP/main
Updated EncryptedSharedPreferences and moved getSpotifyClientPkceApi to a suspend fun
2 parents f1f5453 + 6935157 commit d5f52d8

File tree

3 files changed

+38
-36
lines changed

3 files changed

+38
-36
lines changed

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ tasks {
326326
spotless {
327327
kotlin {
328328
target("**/*.kt")
329-
licenseHeader("/* Spotify Web API, Kotlin Wrapper; MIT License, 2017-2022; Original author: Adam Ratzman */")
329+
licenseHeader("/* Spotify Web API, Kotlin Wrapper; MIT License, 2017-2023; Original author: Adam Ratzman */")
330330
ktlint()
331331
}
332332
}

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ android.useAndroidX=true
88
android.enableJetifier=true
99

1010
# language dependencies
11-
kotlinVersion=1.9.10
11+
kotlinVersion=1.9.20
1212

1313
# library dependencies
1414
kotlinxDatetimeVersion=0.4.1
@@ -19,7 +19,7 @@ kotlinxCoroutinesVersion=1.7.3
1919

2020
androidBuildToolsVersion=8.1.0
2121
androidSpotifyAuthVersion=2.1.0
22-
androidCryptoVersion=1.0.0
22+
androidCryptoVersion=1.1.0-alpha06
2323
androidxCompatVersion=1.6.1
2424

2525
sparkVersion=2.9.4

src/androidMain/kotlin/com/adamratzman/spotify/auth/SpotifyDefaultCredentialStore.kt

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import android.content.SharedPreferences
99
import android.os.Build
1010
import androidx.annotation.RequiresApi
1111
import androidx.security.crypto.EncryptedSharedPreferences
12-
import androidx.security.crypto.MasterKeys
12+
import androidx.security.crypto.MasterKey
1313
import com.adamratzman.spotify.GenericSpotifyApi
1414
import com.adamratzman.spotify.SpotifyApi
1515
import com.adamratzman.spotify.SpotifyApiOptions
@@ -21,7 +21,6 @@ import com.adamratzman.spotify.refreshSpotifyClientToken
2121
import com.adamratzman.spotify.spotifyClientPkceApi
2222
import com.adamratzman.spotify.spotifyImplicitGrantApi
2323
import com.adamratzman.spotify.utils.logToConsole
24-
import kotlinx.coroutines.runBlocking
2524

2625
/**
2726
* Provided credential store for holding current Spotify token credentials, allowing you to easily store and retrieve
@@ -61,7 +60,8 @@ public class SpotifyDefaultCredentialStore(
6160
/**
6261
* The PKCE code verifier key currently being used in [EncryptedSharedPreferences]
6362
*/
64-
public const val SpotifyCurrentPkceCodeVerifierKey: String = "spotifyCurrentPkceCodeVerifier"
63+
public const val SpotifyCurrentPkceCodeVerifierKey: String =
64+
"spotifyCurrentPkceCodeVerifier"
6565

6666
/**
6767
* The activity to return to if re-authentication is necessary on implicit authentication. Null except during authentication when using [guardValidImplicitSpotifyApi]
@@ -71,18 +71,20 @@ public class SpotifyDefaultCredentialStore(
7171

7272
public var credentialTypeStored: CredentialType? = null
7373

74+
private val masterKeyForEncryption =
75+
MasterKey.Builder(applicationContext).setKeyScheme(MasterKey.KeyScheme.AES256_GCM).build()
76+
7477
/**
7578
* The [EncryptedSharedPreferences] that this API saves to/retrieves from.
7679
*/
77-
@Suppress("DEPRECATION")
78-
public val encryptedPreferences: SharedPreferences = EncryptedSharedPreferences
79-
.create(
80-
"spotify-api-encrypted-preferences",
81-
MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
82-
applicationContext,
83-
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
84-
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
85-
)
80+
public val encryptedPreferences: SharedPreferences = EncryptedSharedPreferences.create(
81+
applicationContext,
82+
"spotify-api-encrypted-preferences",
83+
masterKeyForEncryption,
84+
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
85+
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
86+
)
87+
8688

8789
/**
8890
* Get/set when the Spotify access token will expire, in milliseconds from UNIX epoch. This will be one hour from authentication.
@@ -126,7 +128,8 @@ public class SpotifyDefaultCredentialStore(
126128
*/
127129
public var currentSpotifyPkceCodeVerifier: String?
128130
get() = encryptedPreferences.getString(SpotifyCurrentPkceCodeVerifierKey, null)
129-
set(value) = encryptedPreferences.edit().putString(SpotifyCurrentPkceCodeVerifierKey, value).apply()
131+
set(value) = encryptedPreferences.edit().putString(SpotifyCurrentPkceCodeVerifierKey, value)
132+
.apply()
130133

131134
/**
132135
* Get/set the Spotify [Token] obtained from [spotifyToken].
@@ -181,31 +184,27 @@ public class SpotifyDefaultCredentialStore(
181184
*
182185
* @param block Applied configuration to the [SpotifyClientApi]
183186
*/
184-
public fun getSpotifyClientPkceApi(block: ((SpotifyApiOptions).() -> Unit)? = null): SpotifyClientApi? {
187+
public suspend fun getSpotifyClientPkceApi(block: ((SpotifyApiOptions).() -> Unit)? = null): SpotifyClientApi? {
185188
val token = spotifyToken
186189
?: if (spotifyRefreshToken != null) {
187-
runBlocking {
188-
val newToken = refreshSpotifyClientToken(clientId, null, spotifyRefreshToken, true)
189-
spotifyToken = newToken
190-
newToken
191-
}
190+
val newToken = refreshSpotifyClientToken(clientId, null, spotifyRefreshToken, true)
191+
spotifyToken = newToken
192+
newToken
192193
} else {
193194
return null
194195
}
195196

196-
return runBlocking {
197-
spotifyClientPkceApi(
198-
clientId,
199-
redirectUri,
200-
SpotifyUserAuthorization(token = token),
201-
block ?: {}
202-
).build().apply {
203-
val previousAfterTokenRefresh = spotifyApiOptions.afterTokenRefresh
204-
spotifyApiOptions.afterTokenRefresh = {
205-
spotifyToken = this.token
206-
logToConsole("Refreshed Spotify PKCE token in credential store... $token")
207-
previousAfterTokenRefresh?.invoke(this)
208-
}
197+
return spotifyClientPkceApi(
198+
clientId,
199+
redirectUri,
200+
SpotifyUserAuthorization(token = token),
201+
block ?: {}
202+
).build().apply {
203+
val previousAfterTokenRefresh = spotifyApiOptions.afterTokenRefresh
204+
spotifyApiOptions.afterTokenRefresh = {
205+
spotifyToken = this.token
206+
logToConsole("Refreshed Spotify PKCE token in credential store... $token")
207+
previousAfterTokenRefresh?.invoke(this)
209208
}
210209
}
211210
}
@@ -245,6 +244,9 @@ public enum class CredentialType {
245244
}
246245

247246
@RequiresApi(Build.VERSION_CODES.M)
248-
public fun Application.getDefaultCredentialStore(clientId: String, redirectUri: String): SpotifyDefaultCredentialStore {
247+
public fun Application.getDefaultCredentialStore(
248+
clientId: String,
249+
redirectUri: String
250+
): SpotifyDefaultCredentialStore {
249251
return SpotifyDefaultCredentialStore(clientId, redirectUri, applicationContext)
250252
}

0 commit comments

Comments
 (0)