BIT-765: Parse user information from JWT token (#127)

This commit is contained in:
Brian Yencho
2023-10-18 09:21:45 -05:00
committed by Álison Fernandes
parent 4f9f0ce8a7
commit 0c50babd23
5 changed files with 165 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
package com.x8bit.bitwarden.data.auth.repository.model
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
* Contains data that can be parsed from a valid JWT token.
*
* @property userId The ID of the user.
* @property email The user's email address.
* @property isEmailVerified Whether or not the user's email is verified.
* @property name The user's name.
* @property expirationAsEpochTime The expiration time measured as an epoch time in seconds.
* @property hasPremium True if the user has a premium account.
* @property authenticationMethodsReference A list of the authentication methods used during
* authentication.
*/
@Serializable
data class JwtTokenDataJson(
@SerialName("sub")
val userId: String,
@SerialName("email")
val email: String,
@SerialName("email_verified")
val isEmailVerified: Boolean,
@SerialName("name")
val name: String?,
@SerialName("exp")
val expirationAsEpochTime: Int,
@SerialName("premium")
val hasPremium: Boolean,
@SerialName("amr")
val authenticationMethodsReference: List<String>,
)

View File

@@ -0,0 +1,28 @@
package com.x8bit.bitwarden.data.auth.repository.util
import com.x8bit.bitwarden.data.auth.repository.model.JwtTokenDataJson
import com.x8bit.bitwarden.data.platform.datasource.network.util.base64UrlDecodeOrNull
import kotlinx.serialization.json.Json
/**
* Internal, generally basic [Json] instance for JWT parsing purposes.
*/
private val json by lazy { Json { ignoreUnknownKeys = true } }
/**
* Parses a [JwtTokenDataJson] from the given [jwtToken], or `null` if this parsing is not possible.
*/
@Suppress("MagicNumber", "ReturnCount")
fun parseJwtTokenDataOrNull(jwtToken: String): JwtTokenDataJson? {
val parts = jwtToken.split(".")
if (parts.size != 3) return null
val dataJson = parts[1]
val decodedDataJson = dataJson.base64UrlDecodeOrNull() ?: return null
return try {
json.decodeFromString<JwtTokenDataJson>(decodedDataJson)
} catch (_: Throwable) {
null
}
}

View File

@@ -1,5 +1,7 @@
package com.x8bit.bitwarden.data.platform.datasource.network.util
import okio.ByteString.Companion.decodeBase64
import java.nio.charset.Charset
import java.util.Base64
/**
@@ -15,3 +17,18 @@ fun String.base64UrlEncode(): String =
.replace("+", "-")
.replace("/", "_")
.replace("=", "")
/**
* Base 64 decode the given string after making the following replacements:
*
* - replace all "-" with "+"
* - replace all "_" with "/"
*
* A value of `null` will be returned if the decoding fails.
*/
fun String.base64UrlDecodeOrNull(): String? =
this
.replace("-", "+")
.replace("_", "/")
.decodeBase64()
?.string(Charset.defaultCharset())