diff --git a/CHANGELOG.md b/CHANGELOG.md index 81ba5746..8385675b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,12 @@ ## Unreleased -* Fix schema issue in the `Event`, `Message`, and `Draft` models +### Added + +* Add support for getting OAuth token info + +### Changed +* Fix schema issues in the `Event`, `Message`, `Draft`, and `CodeExchangeResponse` models ## [2.0.0] - Released 2024-02-05 diff --git a/src/main/kotlin/com/nylas/models/CodeExchangeResponse.kt b/src/main/kotlin/com/nylas/models/CodeExchangeResponse.kt index 006f543c..637dde26 100644 --- a/src/main/kotlin/com/nylas/models/CodeExchangeResponse.kt +++ b/src/main/kotlin/com/nylas/models/CodeExchangeResponse.kt @@ -26,6 +26,11 @@ data class CodeExchangeResponse( */ @Json(name = "scope") val scope: String, + /** + * Email address of the grant that is created. + */ + @Json(name = "email") + val email: String? = null, /** * Only returned if the code was requested using [AccessType.OFFLINE][com.nylas.models.AccessType.OFFLINE]. */ diff --git a/src/main/kotlin/com/nylas/models/TokenInfoRequest.kt b/src/main/kotlin/com/nylas/models/TokenInfoRequest.kt new file mode 100644 index 00000000..48d9b701 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/TokenInfoRequest.kt @@ -0,0 +1,20 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * A request to query the information of a token. + * @suppress Used internally by the SDK + */ +data class TokenInfoRequest( + /** + * The ID token to query. + */ + @Json(name = "id_token") + val idToken: String? = null, + /** + * The access token to query. + */ + @Json(name = "access_token") + val accessToken: String? = null, +) : IQueryParams diff --git a/src/main/kotlin/com/nylas/models/TokenInfoResponse.kt b/src/main/kotlin/com/nylas/models/TokenInfoResponse.kt new file mode 100644 index 00000000..c060ece5 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/TokenInfoResponse.kt @@ -0,0 +1,36 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +data class TokenInfoResponse( + /** + * The issuer of the token. + */ + @Json(name = "iss") + val iss: String, + /** + * The token's audience. + */ + @Json(name = "aud") + val aud: String, + /** + * The time that the token was issued. + */ + @Json(name = "iat") + val iat: Int, + /** + * The time that the token expires. + */ + @Json(name = "exp") + val exp: Int, + /** + * The token's subject. + */ + @Json(name = "sub") + val sub: String? = null, + /** + * The email address of the Grant belonging to the user's token. + */ + @Json(name = "email") + val email: String? = null, +) diff --git a/src/main/kotlin/com/nylas/resources/Auth.kt b/src/main/kotlin/com/nylas/resources/Auth.kt index a9d971dc..3a4661ff 100644 --- a/src/main/kotlin/com/nylas/resources/Auth.kt +++ b/src/main/kotlin/com/nylas/resources/Auth.kt @@ -148,6 +148,28 @@ class Auth(private val client: NylasClient) { return client.executePost(path, responseType, queryParams = params) } + /** + * Get info about an ID token + * @param idToken The ID token to query + * @return The token information + */ + @Throws(NylasApiError::class, NylasSdkTimeoutError::class) + fun idTokenInfo(idToken: String): Response { + val params = TokenInfoRequest(idToken = idToken) + return getTokenInfo(params) + } + + /** + * Get info about an access token + * @param accessToken The access token to query + * @return The token information + */ + @Throws(NylasApiError::class, NylasSdkTimeoutError::class) + fun accessTokenInfo(accessToken: String): Response { + val params = TokenInfoRequest(accessToken = accessToken) + return getTokenInfo(params) + } + /** * Hash a plain text secret for use in PKCE * @param secret The plain text secret to hash @@ -180,4 +202,10 @@ class Auth(private val client: NylasClient) { return url } + + private fun getTokenInfo(params: TokenInfoRequest): Response { + val path = "v3/connect/tokeninfo" + val responseType = Types.newParameterizedType(Response::class.java, TokenInfoResponse::class.java) + return client.executeGet(path, responseType, queryParams = params) + } } diff --git a/src/test/kotlin/com/nylas/resources/AuthTests.kt b/src/test/kotlin/com/nylas/resources/AuthTests.kt index f1774f1f..f53d6dff 100644 --- a/src/test/kotlin/com/nylas/resources/AuthTests.kt +++ b/src/test/kotlin/com/nylas/resources/AuthTests.kt @@ -318,5 +318,45 @@ class AuthTests { assertNull(requestBodyCaptor.firstValue) assertEquals(true, res) } + + @Test + fun `idTokenInfo calls requests with the correct params`() { + val idToken = "user-id-token" + + auth.idTokenInfo(idToken) + + val pathCaptor = argumentCaptor() + val typeCaptor = argumentCaptor() + val queryParamCaptor = argumentCaptor() + verify(mockNylasClient).executeGet>( + pathCaptor.capture(), + typeCaptor.capture(), + queryParamCaptor.capture(), + ) + + assertEquals("v3/connect/tokeninfo", pathCaptor.firstValue) + assertEquals(Types.newParameterizedType(Response::class.java, TokenInfoResponse::class.java), typeCaptor.firstValue) + assertEquals(TokenInfoRequest(idToken = idToken), queryParamCaptor.firstValue) + } + + @Test + fun `accessTokenInfo calls requests with the correct params`() { + val accessToken = "nylas-access-token" + + auth.accessTokenInfo(accessToken) + + val pathCaptor = argumentCaptor() + val typeCaptor = argumentCaptor() + val queryParamCaptor = argumentCaptor() + verify(mockNylasClient).executeGet>( + pathCaptor.capture(), + typeCaptor.capture(), + queryParamCaptor.capture(), + ) + + assertEquals("v3/connect/tokeninfo", pathCaptor.firstValue) + assertEquals(Types.newParameterizedType(Response::class.java, TokenInfoResponse::class.java), typeCaptor.firstValue) + assertEquals(TokenInfoRequest(accessToken = accessToken), queryParamCaptor.firstValue) + } } }