Skip to content

Commit 1f473d5

Browse files
committed
add pkce builders
1 parent dc3f5c8 commit 1f473d5

File tree

2 files changed

+121
-10
lines changed

2 files changed

+121
-10
lines changed

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

Lines changed: 118 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,35 @@ fun spotifyClientApi(
264264
}
265265
}
266266

267+
/**
268+
* Instantiate a new [SpotifyClientApiBuilder] using an [authCode]
269+
*
270+
*
271+
* @param clientId Spotify [client id](https://developer.spotify.com/documentation/general/guides/app-settings/)
272+
* @param clientSecret Spotify [client secret](https://developer.spotify.com/documentation/general/guides/app-settings/)
273+
* @param redirectUri Spotify [redirect uri](https://developer.spotify.com/documentation/general/guides/app-settings/)
274+
* @param authCode The authorization code retrieved after OAuth authorization
275+
*
276+
* @return Configurable [SpotifyClientApiBuilder] that, when built, creates a new [SpotifyClientApi]
277+
*/
278+
fun spotifyClientApi(
279+
clientId: String?,
280+
clientSecret: String?,
281+
redirectUri: String?,
282+
authCode: String
283+
) = SpotifyClientApiBuilder().apply {
284+
credentials {
285+
this.clientId = clientId
286+
this.clientSecret = clientSecret
287+
this.redirectUri = redirectUri
288+
}
289+
290+
authentication {
291+
authorizationCode = authCode
292+
}
293+
}
294+
295+
267296
/**
268297
* Instantiate a new [SpotifyClientApiBuilder] using a Spotify [clientId], [clientSecret], and [redirectUri],
269298
* with an existing [SpotifyUserAuthorization] and with the ability to configure the api settings by providing a
@@ -309,6 +338,87 @@ fun spotifyClientApi(
309338
*/
310339
fun spotifyClientApi(block: SpotifyClientApiBuilder.() -> Unit) = SpotifyClientApiBuilder().apply(block)
311340

341+
342+
// PKCE Client Api Builders
343+
/*
344+
____________________________
345+
/ This is Authorization Code \
346+
\ authorization (PKCE) /
347+
----------------------------
348+
\ ^__^
349+
\ (oo)\_______
350+
(__)\ )\/\
351+
||----w |
352+
|| ||
353+
*/
354+
355+
356+
/**
357+
* Instantiate a new [SpotifyClientApiBuilder] using an [authCode] and [codeVerifier]. This is for **PKCE authorization**.
358+
*
359+
*
360+
* @param clientId Spotify [client id](https://developer.spotify.com/documentation/general/guides/app-settings/)
361+
* @param clientSecret Spotify [client secret](https://developer.spotify.com/documentation/general/guides/app-settings/)
362+
* @param redirectUri Spotify [redirect uri](https://developer.spotify.com/documentation/general/guides/app-settings/)
363+
* @param authCode The authorization code retrieved after OAuth authorization
364+
* @param codeVerifier Your code verifier plaintext.
365+
*
366+
* @return Configurable [SpotifyClientApiBuilder] that, when built, creates a new [SpotifyClientApi]
367+
*/
368+
fun spotifyClientPkceApi(
369+
clientId: String?,
370+
clientSecret: String?,
371+
redirectUri: String?,
372+
authCode: String,
373+
codeVerifier: String
374+
) = SpotifyClientApiBuilder().apply {
375+
credentials {
376+
this.clientId = clientId
377+
this.clientSecret = clientSecret
378+
this.redirectUri = redirectUri
379+
}
380+
381+
authentication {
382+
authorizationCode = authCode
383+
pkceCodeVerifier = codeVerifier
384+
}
385+
}
386+
387+
/**
388+
* Instantiate a new [SpotifyClientApiBuilder] using an [authCode] and [codeVerifier]. This is for **PKCE authorization**.
389+
*
390+
*
391+
* @param clientId Spotify [client id](https://developer.spotify.com/documentation/general/guides/app-settings/)
392+
* @param clientSecret Spotify [client secret](https://developer.spotify.com/documentation/general/guides/app-settings/)
393+
* @param redirectUri Spotify [redirect uri](https://developer.spotify.com/documentation/general/guides/app-settings/)
394+
* @param authCode The authorization code retrieved after OAuth authorization
395+
* @param codeVerifier Your code verifier plaintext.
396+
* @param block Api settings block
397+
*
398+
* @return Configurable [SpotifyClientApiBuilder] that, when built, creates a new [SpotifyClientApi]
399+
*/
400+
fun spotifyClientPkceApi(
401+
clientId: String?,
402+
clientSecret: String?,
403+
redirectUri: String?,
404+
authCode: String,
405+
codeVerifier: String,
406+
block: SpotifyClientApiBuilder.() -> Unit = {}
407+
) = SpotifyClientApiBuilder().apply {
408+
credentials {
409+
this.clientId = clientId
410+
this.clientSecret = clientSecret
411+
this.redirectUri = redirectUri
412+
}
413+
414+
authentication {
415+
authorizationCode = authCode
416+
pkceCodeVerifier = codeVerifier
417+
}
418+
}.apply(block)
419+
420+
421+
312422
/**
313423
* Spotify API builder
314424
*/
@@ -650,7 +760,7 @@ class SpotifyClientApiBuilder(
650760
options.requestTimeoutMillis,
651761
options.json,
652762
options.refreshTokenProducer,
653-
options.usesPkceAuth
763+
false
654764
)
655765
} catch (e: CancellationException) {
656766
throw e
@@ -692,7 +802,7 @@ class SpotifyClientApiBuilder(
692802
options.requestTimeoutMillis,
693803
options.json,
694804
options.refreshTokenProducer,
695-
options.usesPkceAuth
805+
true
696806
)
697807
} catch (e: CancellationException) {
698808
throw e
@@ -715,7 +825,7 @@ class SpotifyClientApiBuilder(
715825
options.requestTimeoutMillis,
716826
options.json,
717827
options.refreshTokenProducer,
718-
options.usesPkceAuth
828+
false
719829
)
720830
authorization.tokenString != null -> SpotifyClientApi(
721831
clientId,
@@ -739,7 +849,7 @@ class SpotifyClientApiBuilder(
739849
options.requestTimeoutMillis,
740850
options.json,
741851
options.refreshTokenProducer,
742-
options.usesPkceAuth
852+
false
743853
)
744854
else -> throw IllegalArgumentException(
745855
"At least one of: authorizationCode, tokenString, or token must be provided " +
@@ -886,9 +996,10 @@ class SpotifyUserAuthorizationBuilder(
886996
var authorizationCode: String? = null,
887997
var tokenString: String? = null,
888998
var token: Token? = null,
889-
var refreshTokenString: String? = null
999+
var refreshTokenString: String? = null,
1000+
var pkceCodeVerifier: String? = null
8901001
) {
891-
fun build() = SpotifyUserAuthorization(authorizationCode, tokenString, token, refreshTokenString)
1002+
fun build() = SpotifyUserAuthorization(authorizationCode, tokenString, token, refreshTokenString, pkceCodeVerifier)
8921003
}
8931004

8941005
/**
@@ -1001,8 +1112,7 @@ data class SpotifyApiOptions(
10011112
var allowBulkRequests: Boolean,
10021113
var requestTimeoutMillis: Long?,
10031114
var json: Json,
1004-
var refreshTokenProducer: (suspend (SpotifyApi<*, *>) -> Token)?,
1005-
val usesPkceAuth: Boolean = false
1115+
var refreshTokenProducer: (suspend (SpotifyApi<*, *>) -> Token)?
10061116
)
10071117

10081118
@Deprecated("Name has been replaced by `options`", ReplaceWith("SpotifyApiOptions"))

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ class SpotifyAppApi internal constructor(
458458
* An API instance created through client authentication, with access to private information
459459
* managed through the scopes exposed in [token]
460460
*/
461-
open class SpotifyClientApi internal constructor(
461+
open class SpotifyClientApi(
462462
clientId: String?,
463463
clientSecret: String?,
464464
var redirectUri: String?,
@@ -496,6 +496,7 @@ open class SpotifyClientApi internal constructor(
496496
clientSecret: String,
497497
redirectUri: String,
498498
token: Token,
499+
usesPkceAuth: Boolean,
499500
options: SpotifyApiOptions = SpotifyApiOptionsBuilder().build()
500501
) : this(
501502
clientId,
@@ -513,7 +514,7 @@ open class SpotifyClientApi internal constructor(
513514
options.requestTimeoutMillis,
514515
options.json,
515516
options.refreshTokenProducer,
516-
options.usesPkceAuth
517+
usesPkceAuth
517518
)
518519

519520
override val albums: AlbumApi = AlbumApi(this)

0 commit comments

Comments
 (0)