From 1f13435cc4158792eec0bc7d8b0b9e472fe517de Mon Sep 17 00:00:00 2001 From: tada5hi Date: Fri, 23 Feb 2024 19:56:04 +0100 Subject: [PATCH 1/8] feat: expose decode header utility --- packages/jsonwebtoken/index.js | 1 + packages/jsonwebtoken/src/decode.rs | 13 +++++++++++++ packages/jsonwebtoken/src/header.rs | 16 ++++++++++++++++ packages/jsonwebtoken/src/lib.rs | 3 +++ 4 files changed, 33 insertions(+) create mode 100644 packages/jsonwebtoken/src/decode.rs diff --git a/packages/jsonwebtoken/index.js b/packages/jsonwebtoken/index.js index 735c47cd..af07fdc4 100644 --- a/packages/jsonwebtoken/index.js +++ b/packages/jsonwebtoken/index.js @@ -351,3 +351,4 @@ module.exports.sign = nativeBinding.sign module.exports.signSync = nativeBinding.signSync module.exports.verify = nativeBinding.verify module.exports.verifySync = nativeBinding.verifySync +module.exports.decodeHader = nativeBinding.decodeHader diff --git a/packages/jsonwebtoken/src/decode.rs b/packages/jsonwebtoken/src/decode.rs new file mode 100644 index 00000000..ae67b060 --- /dev/null +++ b/packages/jsonwebtoken/src/decode.rs @@ -0,0 +1,13 @@ +use napi::{bindgen_prelude::*}; +use napi_derive::napi; + +use crate::{header::Header}; + +#[napi] +pub fn decode_header( + token: &str +) -> Header { + let result = jsonwebtoken::decode_header(&token); + + let header = Header::from(result.unwrap()); +} \ No newline at end of file diff --git a/packages/jsonwebtoken/src/header.rs b/packages/jsonwebtoken/src/header.rs index 34da8da3..9929b65f 100644 --- a/packages/jsonwebtoken/src/header.rs +++ b/packages/jsonwebtoken/src/header.rs @@ -73,6 +73,22 @@ impl From<&Header> for jsonwebtoken::Header { } } +impl From for Header { + #[inline] + fn from(value: &jsonwebtoken::Header) -> Header { + Header { + algorithm: value.alg.into(), + content_type: value.cty.clone(), + json_key_url: value.jku.clone(), + key_id: value.kid.clone(), + x5_url: value.x5u.clone(), + x5_cert_chain: value.x5c.clone(), + x5_cert_thumbprint: value.x5t.clone(), + x5t_s256_cert_thumbprint: value.x5t_s256.clone(), + } + } +} + impl Header { #[inline] pub fn merge(self, other: Self) -> Self { diff --git a/packages/jsonwebtoken/src/lib.rs b/packages/jsonwebtoken/src/lib.rs index 01f2c49a..0257263f 100644 --- a/packages/jsonwebtoken/src/lib.rs +++ b/packages/jsonwebtoken/src/lib.rs @@ -3,9 +3,11 @@ /// Explicit extern crate to use allocator. extern crate global_alloc; +extern crate core; mod algorithm; mod claims; +mod decode; mod header; mod sign; mod validation; @@ -13,6 +15,7 @@ mod verify; pub use algorithm::Algorithm; pub use claims::Claims; +pub use decode::{decode_header}; pub use header::Header; pub use sign::{sign, sign_sync}; pub use validation::Validation; From d46dfb7735a4429639be516c07c3fb564ccebfbb Mon Sep 17 00:00:00 2001 From: tada5hi Date: Fri, 23 Feb 2024 19:59:08 +0100 Subject: [PATCH 2/8] style: apply linting rules --- packages/jsonwebtoken/src/decode.rs | 14 ++++++-------- packages/jsonwebtoken/src/lib.rs | 4 ++-- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/packages/jsonwebtoken/src/decode.rs b/packages/jsonwebtoken/src/decode.rs index ae67b060..4deb0523 100644 --- a/packages/jsonwebtoken/src/decode.rs +++ b/packages/jsonwebtoken/src/decode.rs @@ -1,13 +1,11 @@ -use napi::{bindgen_prelude::*}; +use napi::bindgen_prelude::*; use napi_derive::napi; -use crate::{header::Header}; +use crate::header::Header; #[napi] -pub fn decode_header( - token: &str -) -> Header { - let result = jsonwebtoken::decode_header(&token); +pub fn decode_header(token: &str) -> Header { + let result = jsonwebtoken::decode_header(&token); - let header = Header::from(result.unwrap()); -} \ No newline at end of file + let header = Header::from(result.unwrap()); +} diff --git a/packages/jsonwebtoken/src/lib.rs b/packages/jsonwebtoken/src/lib.rs index 0257263f..9e948eb9 100644 --- a/packages/jsonwebtoken/src/lib.rs +++ b/packages/jsonwebtoken/src/lib.rs @@ -1,9 +1,9 @@ #![deny(clippy::all)] #![allow(dead_code)] +extern crate core; /// Explicit extern crate to use allocator. extern crate global_alloc; -extern crate core; mod algorithm; mod claims; @@ -15,7 +15,7 @@ mod verify; pub use algorithm::Algorithm; pub use claims::Claims; -pub use decode::{decode_header}; +pub use decode::decode_header; pub use header::Header; pub use sign::{sign, sign_sync}; pub use validation::Validation; From 153a924b8379441572b1ff6a45339c07e017fd39 Mon Sep 17 00:00:00 2001 From: tada5hi Date: Fri, 23 Feb 2024 20:04:26 +0100 Subject: [PATCH 3/8] fix: minor adjustments & add test suite --- .../jsonwebtoken/__tests__/jsonwebtoken.spec.ts | 16 +++++++++++++++- packages/jsonwebtoken/index.d.ts | 1 + packages/jsonwebtoken/src/decode.rs | 1 - packages/jsonwebtoken/src/header.rs | 4 ++-- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/jsonwebtoken/__tests__/jsonwebtoken.spec.ts b/packages/jsonwebtoken/__tests__/jsonwebtoken.spec.ts index 613fed5a..63e16951 100644 --- a/packages/jsonwebtoken/__tests__/jsonwebtoken.spec.ts +++ b/packages/jsonwebtoken/__tests__/jsonwebtoken.spec.ts @@ -4,7 +4,7 @@ import { join } from 'node:path' import test from 'ava' import { decode as nodeJwtDecode } from 'jsonwebtoken' -import { Algorithm, sign, signSync, verifySync, verify } from '../index.js' +import { Algorithm, sign, signSync, verifySync, verify, decodeHeader } from '../index.js' const getUtcTimestamp = () => Math.floor(new Date().getTime() / 1000) const oneDayInSeconds = 86400 @@ -30,6 +30,20 @@ test('signSync and sign (async) should produce the same result', async (t) => { t.truthy(nodeJwtDecode(resAsync)) }) +test('should decode header', async (t) => { + const data = { + id: 'f81d4fae-7dec-11d0-a765-00a0c91e6bf6', + } + const claims = { data, exp: getUtcTimestamp() + oneDayInSeconds } + const secretKey = 'secret' + const headers = { algorithm: Algorithm.HS384 } + + const token = await sign(claims, secretKey, headers) + + const header = decodeHeader(token); + t.is(header.algorithm, Algorithm.HS384); +}) + test('verify should return the decoded claims', async (t) => { const data = { id: 'f81d4fae-7dec-11d0-a765-00a0c91e6bf6', diff --git a/packages/jsonwebtoken/index.d.ts b/packages/jsonwebtoken/index.d.ts index bdb42102..1b4d9ddc 100644 --- a/packages/jsonwebtoken/index.d.ts +++ b/packages/jsonwebtoken/index.d.ts @@ -160,3 +160,4 @@ export function verify(token: string, key: string | Buffer, validation?: Validat export function verifySync(token: string, key: string | Buffer, validation?: Validation | undefined | null): Claims +export function decodeHeader(token: string) : Header; \ No newline at end of file diff --git a/packages/jsonwebtoken/src/decode.rs b/packages/jsonwebtoken/src/decode.rs index 4deb0523..7cdf1c45 100644 --- a/packages/jsonwebtoken/src/decode.rs +++ b/packages/jsonwebtoken/src/decode.rs @@ -1,4 +1,3 @@ -use napi::bindgen_prelude::*; use napi_derive::napi; use crate::header::Header; diff --git a/packages/jsonwebtoken/src/header.rs b/packages/jsonwebtoken/src/header.rs index 9929b65f..d8390627 100644 --- a/packages/jsonwebtoken/src/header.rs +++ b/packages/jsonwebtoken/src/header.rs @@ -73,11 +73,11 @@ impl From<&Header> for jsonwebtoken::Header { } } -impl From for Header { +impl From<&jsonwebtoken::Header> for Header { #[inline] fn from(value: &jsonwebtoken::Header) -> Header { Header { - algorithm: value.alg.into(), + algorithm: value.alg.clone(), content_type: value.cty.clone(), json_key_url: value.jku.clone(), key_id: value.kid.clone(), From 4f7dd78ef019ed5020c27ac231a406d869d14e06 Mon Sep 17 00:00:00 2001 From: tada5hi Date: Fri, 23 Feb 2024 20:07:52 +0100 Subject: [PATCH 4/8] style: apply linting rules in test suite --- packages/jsonwebtoken/__tests__/jsonwebtoken.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/jsonwebtoken/__tests__/jsonwebtoken.spec.ts b/packages/jsonwebtoken/__tests__/jsonwebtoken.spec.ts index 63e16951..44f4c0e6 100644 --- a/packages/jsonwebtoken/__tests__/jsonwebtoken.spec.ts +++ b/packages/jsonwebtoken/__tests__/jsonwebtoken.spec.ts @@ -40,8 +40,8 @@ test('should decode header', async (t) => { const token = await sign(claims, secretKey, headers) - const header = decodeHeader(token); - t.is(header.algorithm, Algorithm.HS384); + const header = decodeHeader(token) + t.is(header.algorithm, Algorithm.HS384) }) test('verify should return the decoded claims', async (t) => { From a9b3d4ff041730d2b5b65940e86f2621fde6574f Mon Sep 17 00:00:00 2001 From: tada5hi Date: Sat, 24 Feb 2024 12:23:41 +0100 Subject: [PATCH 5/8] fix: algorithm transformation & decode header fn --- packages/jsonwebtoken/src/algorithm.rs | 20 ++++++++++++++++++++ packages/jsonwebtoken/src/decode.rs | 5 +++-- packages/jsonwebtoken/src/header.rs | 6 +++--- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/packages/jsonwebtoken/src/algorithm.rs b/packages/jsonwebtoken/src/algorithm.rs index d749d793..ddd98986 100644 --- a/packages/jsonwebtoken/src/algorithm.rs +++ b/packages/jsonwebtoken/src/algorithm.rs @@ -48,6 +48,26 @@ impl From for jsonwebtoken::Algorithm { } } +impl From for Algorithm { + #[inline] + fn from(value: jsonwebtoken::Algorithm) -> Self { + match value { + jsonwebtoken::Algorithm::ES256 => Algorithm::ES256, + jsonwebtoken::Algorithm::ES384 => Algorithm::ES384, + jsonwebtoken::Algorithm::EdDSA => Algorithm::EdDSA, + jsonwebtoken::Algorithm::HS256 => Algorithm::HS256, + jsonwebtoken::Algorithm::HS384 => Algorithm::HS384, + jsonwebtoken::Algorithm::HS512 => Algorithm::HS512, + jsonwebtoken::Algorithm::PS256 => Algorithm::PS256, + jsonwebtoken::Algorithm::PS384 => Algorithm::PS384, + jsonwebtoken::Algorithm::PS512 => Algorithm::PS512, + jsonwebtoken::Algorithm::RS256 => Algorithm::RS256, + jsonwebtoken::Algorithm::RS384 => Algorithm::RS384, + jsonwebtoken::Algorithm::RS512 => Algorithm::RS512, + } + } +} + impl Default for Algorithm { fn default() -> Self { Self::HS256 diff --git a/packages/jsonwebtoken/src/decode.rs b/packages/jsonwebtoken/src/decode.rs index 7cdf1c45..4bff975a 100644 --- a/packages/jsonwebtoken/src/decode.rs +++ b/packages/jsonwebtoken/src/decode.rs @@ -3,8 +3,9 @@ use napi_derive::napi; use crate::header::Header; #[napi] -pub fn decode_header(token: &str) -> Header { +pub fn decode_header(token: String) -> Header { let result = jsonwebtoken::decode_header(&token); - let header = Header::from(result.unwrap()); + let header = result.unwrap().into(); + return header; } diff --git a/packages/jsonwebtoken/src/header.rs b/packages/jsonwebtoken/src/header.rs index d8390627..632fb51e 100644 --- a/packages/jsonwebtoken/src/header.rs +++ b/packages/jsonwebtoken/src/header.rs @@ -73,11 +73,11 @@ impl From<&Header> for jsonwebtoken::Header { } } -impl From<&jsonwebtoken::Header> for Header { +impl From for Header { #[inline] - fn from(value: &jsonwebtoken::Header) -> Header { + fn from(value: jsonwebtoken::Header) -> Header { Header { - algorithm: value.alg.clone(), + algorithm: Algorithm::from(value.alg.clone()).into(), content_type: value.cty.clone(), json_key_url: value.jku.clone(), key_id: value.kid.clone(), From e5f465f4f84db4001a27a396699f728d65390348 Mon Sep 17 00:00:00 2001 From: tada5hi Date: Sat, 24 Feb 2024 12:25:31 +0100 Subject: [PATCH 6/8] style: apply linting rules --- packages/jsonwebtoken/src/algorithm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jsonwebtoken/src/algorithm.rs b/packages/jsonwebtoken/src/algorithm.rs index ddd98986..4ca8aa3c 100644 --- a/packages/jsonwebtoken/src/algorithm.rs +++ b/packages/jsonwebtoken/src/algorithm.rs @@ -56,7 +56,7 @@ impl From for Algorithm { jsonwebtoken::Algorithm::ES384 => Algorithm::ES384, jsonwebtoken::Algorithm::EdDSA => Algorithm::EdDSA, jsonwebtoken::Algorithm::HS256 => Algorithm::HS256, - jsonwebtoken::Algorithm::HS384 => Algorithm::HS384, + jsonwebtoken::Algorithm::HS384 => Algorithm::HS384, jsonwebtoken::Algorithm::HS512 => Algorithm::HS512, jsonwebtoken::Algorithm::PS256 => Algorithm::PS256, jsonwebtoken::Algorithm::PS384 => Algorithm::PS384, From 7a3bdc83e749064f9bbb6c32eb8a9f0d29b39c33 Mon Sep 17 00:00:00 2001 From: tada5hi Date: Sat, 24 Feb 2024 12:31:59 +0100 Subject: [PATCH 7/8] fix: apply clippy suggestions --- packages/jsonwebtoken/src/decode.rs | 2 +- packages/jsonwebtoken/src/header.rs | 2 +- packages/jsonwebtoken/src/lib.rs | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/jsonwebtoken/src/decode.rs b/packages/jsonwebtoken/src/decode.rs index 4bff975a..87250114 100644 --- a/packages/jsonwebtoken/src/decode.rs +++ b/packages/jsonwebtoken/src/decode.rs @@ -7,5 +7,5 @@ pub fn decode_header(token: String) -> Header { let result = jsonwebtoken::decode_header(&token); let header = result.unwrap().into(); - return header; + header } diff --git a/packages/jsonwebtoken/src/header.rs b/packages/jsonwebtoken/src/header.rs index 632fb51e..cf402294 100644 --- a/packages/jsonwebtoken/src/header.rs +++ b/packages/jsonwebtoken/src/header.rs @@ -77,7 +77,7 @@ impl From for Header { #[inline] fn from(value: jsonwebtoken::Header) -> Header { Header { - algorithm: Algorithm::from(value.alg.clone()).into(), + algorithm: Algorithm::from(value.alg).into(), content_type: value.cty.clone(), json_key_url: value.jku.clone(), key_id: value.kid.clone(), diff --git a/packages/jsonwebtoken/src/lib.rs b/packages/jsonwebtoken/src/lib.rs index 9e948eb9..9dc180e2 100644 --- a/packages/jsonwebtoken/src/lib.rs +++ b/packages/jsonwebtoken/src/lib.rs @@ -1,7 +1,6 @@ #![deny(clippy::all)] #![allow(dead_code)] -extern crate core; /// Explicit extern crate to use allocator. extern crate global_alloc; From a475994d82ad53c6140953330d0d12c23524ec10 Mon Sep 17 00:00:00 2001 From: tada5hi Date: Sat, 24 Feb 2024 16:54:14 +0100 Subject: [PATCH 8/8] fix: simplified decode_header fn & generated index.{js,d.ts} --- packages/jsonwebtoken/index.d.ts | 3 ++- packages/jsonwebtoken/index.js | 2 +- packages/jsonwebtoken/src/decode.rs | 3 +-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/jsonwebtoken/index.d.ts b/packages/jsonwebtoken/index.d.ts index 1b4d9ddc..a96c1f24 100644 --- a/packages/jsonwebtoken/index.d.ts +++ b/packages/jsonwebtoken/index.d.ts @@ -28,6 +28,8 @@ export const enum Algorithm { EdDSA = 11 } +export function decodeHeader(token: string): Header + export interface Header { /** * The algorithm used @@ -160,4 +162,3 @@ export function verify(token: string, key: string | Buffer, validation?: Validat export function verifySync(token: string, key: string | Buffer, validation?: Validation | undefined | null): Claims -export function decodeHeader(token: string) : Header; \ No newline at end of file diff --git a/packages/jsonwebtoken/index.js b/packages/jsonwebtoken/index.js index af07fdc4..1759598f 100644 --- a/packages/jsonwebtoken/index.js +++ b/packages/jsonwebtoken/index.js @@ -347,8 +347,8 @@ if (!nativeBinding) { } module.exports.Algorithm = nativeBinding.Algorithm +module.exports.decodeHeader = nativeBinding.decodeHeader module.exports.sign = nativeBinding.sign module.exports.signSync = nativeBinding.signSync module.exports.verify = nativeBinding.verify module.exports.verifySync = nativeBinding.verifySync -module.exports.decodeHader = nativeBinding.decodeHader diff --git a/packages/jsonwebtoken/src/decode.rs b/packages/jsonwebtoken/src/decode.rs index 87250114..f802f443 100644 --- a/packages/jsonwebtoken/src/decode.rs +++ b/packages/jsonwebtoken/src/decode.rs @@ -6,6 +6,5 @@ use crate::header::Header; pub fn decode_header(token: String) -> Header { let result = jsonwebtoken::decode_header(&token); - let header = result.unwrap().into(); - header + result.unwrap().into() }