Skip to content

Commit

Permalink
feat(jsonwebtoken): expose decode header utility (#795)
Browse files Browse the repository at this point in the history
* feat: expose decode header utility

* style: apply linting rules

* fix: minor adjustments & add test suite

* style: apply linting rules in test suite

* fix: algorithm transformation & decode header fn

* style: apply linting rules

* fix: apply clippy suggestions

* fix: simplified decode_header fn & generated index.{js,d.ts}
  • Loading branch information
tada5hi committed Feb 26, 2024
1 parent 5993557 commit fc259ce
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 1 deletion.
16 changes: 15 additions & 1 deletion packages/jsonwebtoken/__tests__/jsonwebtoken.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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',
Expand Down
2 changes: 2 additions & 0 deletions packages/jsonwebtoken/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export const enum Algorithm {
EdDSA = 11
}

export function decodeHeader(token: string): Header

export interface Header {
/**
* The algorithm used
Expand Down
1 change: 1 addition & 0 deletions packages/jsonwebtoken/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ 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
Expand Down
20 changes: 20 additions & 0 deletions packages/jsonwebtoken/src/algorithm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,26 @@ impl From<Algorithm> for jsonwebtoken::Algorithm {
}
}

impl From<jsonwebtoken::Algorithm> 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
Expand Down
10 changes: 10 additions & 0 deletions packages/jsonwebtoken/src/decode.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use napi_derive::napi;

use crate::header::Header;

#[napi]
pub fn decode_header(token: String) -> Header {
let result = jsonwebtoken::decode_header(&token);

result.unwrap().into()
}
16 changes: 16 additions & 0 deletions packages/jsonwebtoken/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,22 @@ impl From<&Header> for jsonwebtoken::Header {
}
}

impl From<jsonwebtoken::Header> for Header {
#[inline]
fn from(value: jsonwebtoken::Header) -> Header {
Header {
algorithm: Algorithm::from(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 {
Expand Down
2 changes: 2 additions & 0 deletions packages/jsonwebtoken/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ extern crate global_alloc;

mod algorithm;
mod claims;
mod decode;
mod header;
mod sign;
mod validation;
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;
Expand Down

0 comments on commit fc259ce

Please sign in to comment.