From 0f3b9bfe9acc7db0cf3c0fbc1b8875363e157dc9 Mon Sep 17 00:00:00 2001 From: Jonathan Bernard Date: Wed, 1 Jan 2025 11:34:53 -0600 Subject: [PATCH] Add quick accessors for more common JWT claims. --- jwt_full.nimble | 2 +- src/main/jwt_full/claims.nim | 42 ++++++++++++++++++++++-------------- src/main/jwt_full/jwt.nim | 2 +- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/jwt_full.nimble b/jwt_full.nimble index 2de4641..ef161bc 100644 --- a/jwt_full.nimble +++ b/jwt_full.nimble @@ -1,6 +1,6 @@ # Package -version = "0.2.0" +version = "0.3.0" author = "Jonathan Bernard" description = "Full JWT, JWS, JWE, and JWK implementation for Nim, compliant with RFCs 7515-7519." license = "GPL-3.0-or-later" diff --git a/src/main/jwt_full/claims.nim b/src/main/jwt_full/claims.nim index 25228db..e0abcc2 100644 --- a/src/main/jwt_full/claims.nim +++ b/src/main/jwt_full/claims.nim @@ -25,25 +25,29 @@ type JwtClaims* = object rawB64: string json: JsonNode - iss: Option[string] - sub: Option[string] aud: Option[string] exp: Option[DateTime] - nbf: Option[DateTime] iat: Option[DateTime] + iss: Option[string] jti: Option[string] + nbf: Option[DateTime] + sid: Option[string] + sub: Option[string] + typ: Option[string] # Public read-only accessors to JwtClaims members # ----------------------------------------------- func rawB64*(c: JwtClaims): string = c.rawB64 -func iss*(c: JwtClaims): Option[string] = c.iss -func sub*(c: JwtClaims): Option[string] = c.sub func aud*(c: JwtClaims): Option[string] = c.aud func exp*(c: JwtClaims): Option[DateTime] = c.exp -func nbf*(c: JwtClaims): Option[DateTime] = c.nbf func iat*(c: JwtClaims): Option[DateTime] = c.iat +func iss*(c: JwtClaims): Option[string] = c.iss func jti*(c: JwtClaims): Option[string] = c.jti +func nbf*(c: JwtClaims): Option[DateTime] = c.nbf +func sid*(c: JwtClaims): Option[string] = c.sid +func sub*(c: JwtClaims): Option[string] = c.sub +func typ*(c: JwtClaims): Option[string] = c.typ func `[]`*(c: JwtClaims, key: string): Option[JsonNode] = ## Generic accessor to claim values by name @@ -61,13 +65,15 @@ proc initJwtClaims*(n: JsonNode): JwtClaims = return JwtClaims( rawB64: b64UrlEncode($n), json: n, - iss: n.optStrVal("iss"), - sub: n.optStrVal("sub"), aud: n.optStrVal("aud"), exp: n.optNumericDate("exp"), - nbf: n.optNumericDate("nbf"), iat: n.optNumericDate("iat"), - jti: n.optStrVal("jtu")) + iss: n.optStrVal("iss"), + jti: n.optStrVal("jtu"), + nbf: n.optNumericDate("nbf"), + sid: n.optStrVal("sid"), + sub: n.optStrVal("sub"), + typ: n.optStrVal("typ")) proc initJwtClaims*(encoded: string): JwtClaims = ## Parse a Base64url-encoded set of claims into a JwtClaims object @@ -77,13 +83,15 @@ proc initJwtClaims*(encoded: string): JwtClaims = result.rawB64 = encoded proc initJwtClaims*( - iss: Option[string] = none[string](), - sub: Option[string] = none[string](), aud: Option[string] = none[string](), exp: Option[DateTime] = none[DateTime](), - nbf: Option[DateTime] = none[DateTime](), iat: Option[DateTime] = none[DateTime](), + iss: Option[string] = none[string](), jti: Option[string] = none[string](), + nbf: Option[DateTime] = none[DateTime](), + sid: Option[string] = none[string](), + sub: Option[string] = none[string](), + typ: Option[string] = none[string](), moreClaims: seq[tuple[k, v: string]] = @[] ): JwtClaims = ## Convenience method to initialize a new JwtClaims object by specifying @@ -99,12 +107,14 @@ proc initJwtClaims*( let json = newJObject() for claim in moreClaims: json[claim.k] = %claim.v - if iss.isSome: json["iss"] = %iss.get - if sub.isSome: json["sub"] = %sub.get if aud.isSome: json["aud"] = %aud.get if exp.isSome: json["exp"] = %toNumericDate(exp.get) - if nbf.isSome: json["nbf"] = %toNumericDate(nbf.get) if iat.isSome: json["iat"] = %toNumericDate(iat.get) + if iss.isSome: json["iss"] = %iss.get if jti.isSome: json["jti"] = %jti.get + if nbf.isSome: json["nbf"] = %toNumericDate(nbf.get) + if sid.isSome: json["sid"] = %sid.get + if sub.isSome: json["sub"] = %sub.get + if typ.isSome: json["typ"] = %typ.get return initJwtClaims(json) diff --git a/src/main/jwt_full/jwt.nim b/src/main/jwt_full/jwt.nim index 9d4ecf5..5b55909 100644 --- a/src/main/jwt_full/jwt.nim +++ b/src/main/jwt_full/jwt.nim @@ -57,7 +57,7 @@ proc initJWT*(encoded: string): JWT = jws: jws) else: # TODO - raise newException(Exception, "not yet implemented") + raise newException(Exception, "partial JWT construction is not yet implemented") proc toJWT*(encoded: string): JWT = initJWT(encoded)