simplify kt
This commit is contained in:
+4
-22
@@ -22,7 +22,7 @@ class CryptoUtil {
|
||||
return random
|
||||
}
|
||||
|
||||
fun generateKeyPair(): Any {
|
||||
fun generateKeyPair(): Map<String, String> {
|
||||
val keyIdString = UUID.randomUUID().toString()
|
||||
|
||||
val keyPairGen = KeyPairGenerator.getInstance("EC")
|
||||
@@ -44,27 +44,9 @@ class CryptoUtil {
|
||||
.algorithm(Algorithm.parse("ES256"))
|
||||
.build()
|
||||
|
||||
|
||||
return JWKPair(
|
||||
JWK(
|
||||
alg = privateJwk.algorithm.toString(),
|
||||
kty = privateJwk.keyType.toString(),
|
||||
crv = privateJwk.curve.toString(),
|
||||
x = privateJwk.x.toString(),
|
||||
y = privateJwk.y.toString(),
|
||||
d = privateJwk.d.toString(),
|
||||
use = privateJwk.keyUse.toString(),
|
||||
kid = privateJwk.keyID
|
||||
),
|
||||
JWK(
|
||||
alg = publicJwk.algorithm.toString(),
|
||||
kty = publicJwk.keyType.toString(),
|
||||
crv = publicJwk.curve.toString(),
|
||||
x = publicJwk.x.toString(),
|
||||
y = publicJwk.y.toString(),
|
||||
use = publicJwk.keyUse.toString(),
|
||||
kid = publicJwk.keyID
|
||||
)
|
||||
return mapOf(
|
||||
"privateKey" to privateJwk.toJSONString(),
|
||||
"publicKey" to publicJwk.toJSONString()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -17,14 +17,14 @@ class ExpoBlueskyOAuthClientModule : Module() {
|
||||
return@Function CryptoUtil().getRandomValues(byteLength)
|
||||
}
|
||||
|
||||
AsyncFunction("generateJwk") { algorithim: String ->
|
||||
AsyncFunction("generateJwk") { algorithim: String? ->
|
||||
if (algorithim != "ES256") {
|
||||
throw Exception("Unsupported algorithm")
|
||||
}
|
||||
return@AsyncFunction CryptoUtil().generateKeyPair()
|
||||
}
|
||||
|
||||
AsyncFunction("createJwt") { header: JWTHeader, payload: JWTPayload, jwk: JWK ->
|
||||
AsyncFunction("createJwt") { header: String, payload: String, jwk: String ->
|
||||
return@AsyncFunction JWTUtil().createJwt(header, payload, jwk)
|
||||
}
|
||||
|
||||
|
||||
+4
-29
@@ -3,32 +3,7 @@ package expo.modules.blueskyoauthclient
|
||||
import expo.modules.kotlin.records.Record
|
||||
import expo.modules.kotlin.records.Field
|
||||
|
||||
class JWK(
|
||||
@Field var alg: String = "",
|
||||
@Field var kty: String = "",
|
||||
@Field var crv: String? = null,
|
||||
@Field var x: String? = null,
|
||||
@Field var y: String? = null,
|
||||
@Field var e: String? = null,
|
||||
@Field var n: String? = null,
|
||||
@Field var d: String? = null,
|
||||
@Field var use: String? = null,
|
||||
@Field var kid: String? = null
|
||||
) : Record {
|
||||
fun toJson(): String {
|
||||
val parts = mutableListOf<String>()
|
||||
if (alg.isNotEmpty()) parts.add("\"alg\": \"$alg\"")
|
||||
if (kty.isNotEmpty()) parts.add("\"kty\": \"$kty\"")
|
||||
if (crv != null) parts.add("\"crv\": \"$crv\"")
|
||||
if (x != null) parts.add("\"x\": \"$x\"")
|
||||
if (y != null) parts.add("\"y\": \"$y\"")
|
||||
if (e != null) parts.add("\"e\": \"$e\"")
|
||||
if (n != null) parts.add("\"n\": \"$n\"")
|
||||
if (d != null) parts.add("\"d\": \"$d\"")
|
||||
if (use != null) parts.add("\"use\": \"$use\"")
|
||||
if (kid != null) parts.add("\"kid\": \"$kid\"")
|
||||
return "{ ${parts.joinToString()} }"
|
||||
}
|
||||
}
|
||||
|
||||
class JWKPair(@Field val privateKey: JWK, @Field val publicKey: JWK) : Record
|
||||
class JWKPair(
|
||||
@Field val privateKey: String,
|
||||
@Field val publicKey: String
|
||||
) : Record
|
||||
+2
-168
@@ -3,173 +3,7 @@ package expo.modules.blueskyoauthclient
|
||||
import expo.modules.kotlin.records.Record
|
||||
import expo.modules.kotlin.records.Field
|
||||
|
||||
class JWTHeader(
|
||||
@Field var alg: String = "",
|
||||
@Field var jku: String? = null,
|
||||
@Field var jwk: JWK? = null,
|
||||
@Field var kid: String? = null,
|
||||
@Field var typ: String? = null,
|
||||
@Field var cty: String? = null,
|
||||
@Field var crit: String? = null
|
||||
) : Record {
|
||||
fun toJson(): String {
|
||||
val parts = mutableListOf<String>()
|
||||
if (alg.isNotEmpty()) parts.add("\"alg\": \"$alg\"")
|
||||
if (jku != null) parts.add("\"jku\": \"$jku\"")
|
||||
if (jwk != null) parts.add("\"jwk\": ${jwk?.toJson()}")
|
||||
if (kid != null) parts.add("\"kid\": \"$kid\"")
|
||||
if (typ != null) parts.add("\"typ\": \"$typ\"")
|
||||
if (cty != null) parts.add("\"cty\": \"$cty\"")
|
||||
if (crit != null) parts.add("\"crit\": \"$crit\"")
|
||||
return "{ ${parts.joinToString()} }"
|
||||
}
|
||||
}
|
||||
|
||||
class JWTPayload(
|
||||
@Field var iss: String? = null,
|
||||
@Field var aud: String? = null,
|
||||
@Field var sub: String? = null,
|
||||
@Field var exp: Int? = null,
|
||||
@Field var nbr: Int? = null,
|
||||
@Field var iat: Int? = null,
|
||||
@Field var jti: String? = null,
|
||||
@Field var htm: String? = null,
|
||||
@Field var htu: String? = null,
|
||||
@Field var ath: String? = null,
|
||||
@Field var acr: String? = null,
|
||||
@Field var azp: String? = null,
|
||||
@Field var amr: String? = null,
|
||||
@Field var cnf: JWTPayloadCNF? = null,
|
||||
@Field var client_id: String? = null,
|
||||
@Field var scope: String? = null,
|
||||
@Field var nonce: String? = null,
|
||||
@Field var at_hash: String? = null,
|
||||
@Field var c_hash: String? = null,
|
||||
@Field var s_hash: String? = null,
|
||||
@Field var auth_time: Int? = null,
|
||||
@Field var name: String? = null,
|
||||
@Field var family_name: String? = null,
|
||||
@Field var given_name: String? = null,
|
||||
@Field var middle_name: String? = null,
|
||||
@Field var nickname: String? = null,
|
||||
@Field var preferred_username: String? = null,
|
||||
@Field var gender: String? = null,
|
||||
@Field var picture: String? = null,
|
||||
@Field var profile: String? = null,
|
||||
@Field var birthdate: String? = null,
|
||||
@Field var zoneinfo: String? = null,
|
||||
@Field var updated_at: Int? = null,
|
||||
@Field var email: String? = null,
|
||||
@Field var email_verified: Boolean? = null,
|
||||
@Field var phone_number: String? = null,
|
||||
@Field var phone_number_verified: Boolean? = null,
|
||||
@Field var address: JWTPayloadAddress? = null,
|
||||
@Field var authorization_details: JWTPayloadAuthorizationDetails? = null
|
||||
) : Record {
|
||||
fun toJson(): String {
|
||||
val parts = mutableListOf<String>()
|
||||
if (iss != null) parts.add("\"iss\": \"$iss\"")
|
||||
if (aud != null) parts.add("\"aud\": \"$aud\"")
|
||||
if (sub != null) parts.add("\"sub\": \"$sub\"")
|
||||
if (exp != null) parts.add("\"exp\": $exp")
|
||||
if (nbr != null) parts.add("\"nbr\": $nbr")
|
||||
if (iat != null) parts.add("\"iat\": $iat")
|
||||
if (jti != null) parts.add("\"jti\": \"$jti\"")
|
||||
if (htm != null) parts.add("\"htm\": \"$htm\"")
|
||||
if (htu != null) parts.add("\"htu\": \"$htu\"")
|
||||
if (ath != null) parts.add("\"ath\": \"$ath\"")
|
||||
if (acr != null) parts.add("\"acr\": \"$acr\"")
|
||||
if (azp != null) parts.add("\"azp\": \"$azp\"")
|
||||
if (amr != null) parts.add("\"amr\": \"$amr\"")
|
||||
if (cnf != null) parts.add("\"cnf\": ${cnf?.toJson()}")
|
||||
if (client_id != null) parts.add("\"client_id\": \"$client_id\"")
|
||||
if (scope != null) parts.add("\"scope\": \"$scope\"")
|
||||
if (nonce != null) parts.add("\"nonce\": \"$nonce\"")
|
||||
if (at_hash != null) parts.add("\"at_hash\": \"$at_hash\"")
|
||||
if (c_hash != null) parts.add("\"c_hash\": \"$c_hash\"")
|
||||
if (s_hash != null) parts.add("\"s_hash\": \"$s_hash\"")
|
||||
if (auth_time != null) parts.add("\"auth_time\": $auth_time")
|
||||
if (name != null) parts.add("\"name\": \"$name\"")
|
||||
if (family_name != null) parts.add("\"family_name\": \"$family_name\"")
|
||||
if (given_name != null) parts.add("\"given_name\": \"$given_name\"")
|
||||
if (middle_name != null) parts.add("\"middle_name\": \"$middle_name\"")
|
||||
if (nickname != null) parts.add("\"nickname\": \"$nickname\"")
|
||||
if (preferred_username != null) parts.add("\"preferred_username\": \"$preferred_username\"")
|
||||
if (gender != null) parts.add("\"gender\": \"$gender\"")
|
||||
if (picture != null) parts.add("\"picture\": \"$picture\"")
|
||||
if (profile != null) parts.add("\"profile\": \"$profile\"")
|
||||
if (birthdate != null) parts.add("\"birthdate\": \"$birthdate\"")
|
||||
if (zoneinfo != null) parts.add("\"zoneinfo\": \"$zoneinfo\"")
|
||||
if (updated_at != null) parts.add("\"updated_at\": $updated_at")
|
||||
if (email != null) parts.add("\"email\": \"$email\"")
|
||||
if (email_verified != null) parts.add("\"email_verified\": $email_verified")
|
||||
if (phone_number != null) parts.add("\"phone_number\": \"$phone_number\"")
|
||||
if (phone_number_verified != null) parts.add("\"phone_number_verified\": $phone_number_verified")
|
||||
if (address != null) parts.add("\"address\": ${address?.toJson()}")
|
||||
if (authorization_details != null) parts.add("\"authorization_details\": ${authorization_details?.toJson()}")
|
||||
return "{ ${parts.joinToString()} }"
|
||||
}
|
||||
}
|
||||
|
||||
class JWTPayloadCNF(
|
||||
@Field var jwk: JWK? = null,
|
||||
@Field var jwe: String? = null,
|
||||
@Field var jku: String? = null,
|
||||
@Field var jkt: String? = null,
|
||||
@Field var osc: String? = null
|
||||
) : Record {
|
||||
fun toJson(): String {
|
||||
val parts = mutableListOf<String>()
|
||||
if (jwk != null) parts.add("\"jwk\": ${jwk?.toJson()}")
|
||||
if (jwe != null) parts.add("\"jwe\": \"$jwe\"")
|
||||
if (jku != null) parts.add("\"jku\": \"$jku\"")
|
||||
if (jkt != null) parts.add("\"jkt\": \"$jkt\"")
|
||||
if (osc != null) parts.add("\"osc\": \"$osc\"")
|
||||
return "{ ${parts.joinToString()} }"
|
||||
}
|
||||
}
|
||||
|
||||
class JWTPayloadAddress(
|
||||
@Field var formatted: String? = null,
|
||||
@Field var street_address: String? = null,
|
||||
@Field var locality: String? = null,
|
||||
@Field var region: String? = null,
|
||||
@Field var postal_code: String? = null,
|
||||
@Field var country: String? = null
|
||||
) : Record {
|
||||
fun toJson(): String {
|
||||
val parts = mutableListOf<String>()
|
||||
if (formatted != null) parts.add("\"formatted\": \"$formatted\"")
|
||||
if (street_address != null) parts.add("\"street_address\": \"$street_address\"")
|
||||
if (locality != null) parts.add("\"locality\": \"$locality\"")
|
||||
if (region != null) parts.add("\"region\": \"$region\"")
|
||||
if (postal_code != null) parts.add("\"postal_code\": \"$postal_code\"")
|
||||
if (country != null) parts.add("\"country\": \"$country\"")
|
||||
return "{ ${parts.joinToString()} }"
|
||||
}
|
||||
}
|
||||
|
||||
class JWTPayloadAuthorizationDetails(
|
||||
@Field var type: String? = null,
|
||||
@Field var locations: Array<String>? = null,
|
||||
@Field var actions: Array<String>? = null,
|
||||
@Field var datatypes: Array<String>? = null,
|
||||
@Field var identifier: String? = null,
|
||||
@Field var privileges: Array<String>? = null
|
||||
) : Record {
|
||||
fun toJson(): String {
|
||||
val parts = mutableListOf<String>()
|
||||
if (type != null) parts.add("\"type\": \"$type\"")
|
||||
if (locations != null) parts.add("\"locations\": [${locations?.joinToString()}]")
|
||||
if (actions != null) parts.add("\"actions\": [${actions?.joinToString()}]")
|
||||
if (datatypes != null) parts.add("\"datatypes\": [${datatypes?.joinToString()}]")
|
||||
if (identifier != null) parts.add("\"identifier\": \"$identifier\"")
|
||||
if (privileges != null) parts.add("\"privileges\": [${privileges?.joinToString()}]")
|
||||
return "{ ${parts.joinToString()} }"
|
||||
}
|
||||
}
|
||||
|
||||
class JWTVerifyResponse(
|
||||
@Field var protectedHeader: JWTHeader = JWTHeader(),
|
||||
@Field var payload: String = "",
|
||||
@Field var protectedHeader: String,
|
||||
@Field var payload: String,
|
||||
) : Record
|
||||
+9
-35
@@ -8,10 +8,10 @@ import com.nimbusds.jwt.JWTClaimsSet
|
||||
import com.nimbusds.jwt.SignedJWT
|
||||
|
||||
class JWTUtil {
|
||||
fun createJwt(header: JWTHeader, payload: JWTPayload, jwk: JWK): String {
|
||||
val parsedKey = ECKey.parse(jwk.toJson())
|
||||
val parsedHeader = JWSHeader.parse(header.toJson())
|
||||
val parsedPayload = JWTClaimsSet.parse(payload.toJson())
|
||||
fun createJwt(header: String, payload: String, jwk: String): String {
|
||||
val parsedKey = ECKey.parse(jwk)
|
||||
val parsedHeader = JWSHeader.parse(header)
|
||||
val parsedPayload = JWTClaimsSet.parse(payload)
|
||||
|
||||
val signer = ECDSASigner(parsedKey)
|
||||
val jwt = SignedJWT(parsedHeader, parsedPayload)
|
||||
@@ -20,9 +20,9 @@ class JWTUtil {
|
||||
return jwt.serialize()
|
||||
}
|
||||
|
||||
fun verifyJwt(token: String, jwk: JWK): JWTVerifyResponse {
|
||||
fun verifyJwt(token: String, jwk: String): Map<String, String> {
|
||||
try {
|
||||
val parsedKey = ECKey.parse(jwk.toJson())
|
||||
val parsedKey = ECKey.parse(jwk)
|
||||
val jwt = SignedJWT.parse(token)
|
||||
val verifier = ECDSAVerifier(parsedKey)
|
||||
|
||||
@@ -32,36 +32,10 @@ class JWTUtil {
|
||||
|
||||
val header = jwt.header
|
||||
val payload = jwt.payload
|
||||
val ecKey = header.jwk?.toECKey()
|
||||
val serializedJwk = if (ecKey != null) {
|
||||
JWK(
|
||||
alg = ecKey.algorithm.toString(),
|
||||
kty = ecKey.keyType.toString(),
|
||||
crv = ecKey.curve.toString(),
|
||||
x = ecKey.x.toString(),
|
||||
y = ecKey.y.toString(),
|
||||
d = ecKey.d.toString(),
|
||||
use = ecKey.keyUse.toString(),
|
||||
kid = ecKey.keyID
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
val serializedHeader = JWTHeader(
|
||||
alg = header.algorithm.toString(),
|
||||
jku = header.jwkurl?.toString(),
|
||||
jwk = serializedJwk,
|
||||
kid = header.keyID,
|
||||
typ = header.type?.toString(),
|
||||
cty = header.contentType,
|
||||
crit = header.criticalParams?.joinToString()
|
||||
)
|
||||
val serializedPayload = payload.toString()
|
||||
|
||||
return JWTVerifyResponse(
|
||||
protectedHeader = serializedHeader,
|
||||
payload = serializedPayload,
|
||||
return mapOf(
|
||||
"payload" to payload.toString(),
|
||||
"protectedHeader" to header.toString()
|
||||
)
|
||||
} catch(e: Exception) {
|
||||
throw e
|
||||
|
||||
Reference in New Issue
Block a user