Skip to content

Commit

Permalink
feat(jsonwebtoken): flatten claims to align with rfc (#780)
Browse files Browse the repository at this point in the history
  • Loading branch information
tada5hi committed Feb 23, 2024
1 parent 7f436e8 commit 89f2ce3
Show file tree
Hide file tree
Showing 9 changed files with 32 additions and 90 deletions.
6 changes: 0 additions & 6 deletions packages/crc32/__tests__/__snapshots__/index.spec.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,3 @@ Generated by [AVA](https://avajs.dev).
> Snapshot 1
614479218

## crc32c result should be equal with sse4_crc32 when caclulate with initial crc

> Snapshot 1
614479218
Binary file modified packages/crc32/__tests__/__snapshots__/index.spec.ts.snap
Binary file not shown.
Binary file modified packages/jieba/__tests__/__snapshots__/jieba.spec.ts.snap
Binary file not shown.
4 changes: 3 additions & 1 deletion packages/jsonwebtoken/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ crate-type = ["cdylib"]

[dependencies]
global_alloc = { path = "../../crates/alloc" }
indexmap = { version = "2", features = ["serde"] }
jsonwebtoken = { version = "9" }
napi = { version = "2", default-features = false, features = [
"napi3",
"serde-json",
"serde-json-ordered",
"object_indexmap",
] }
napi-derive = { version = "2" }
rand_core = { version = "0.6", features = ["std"] }
Expand Down
4 changes: 3 additions & 1 deletion packages/jsonwebtoken/__tests__/jsonwebtoken.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const getUtcTimestamp = () => Math.floor(new Date().getTime() / 1000)
const oneDayInSeconds = 86400

test('signSync and sign (async) should produce the same result', async (t) => {
const iat = getUtcTimestamp()
const claims = {
data: {
id: 'f81d4fae-7dec-11d0-a765-00a0c91e6bf6',
Expand All @@ -18,7 +19,8 @@ test('signSync and sign (async) should produce the same result', async (t) => {
set: ['KL', 'TV', 'JI'],
nest: { id: 'poly' },
},
exp: getUtcTimestamp() + oneDayInSeconds,
exp: iat + oneDayInSeconds,
iat,
}
const secretKey = 'secret'
const resSync = signSync(claims, secretKey)
Expand Down
15 changes: 2 additions & 13 deletions packages/jsonwebtoken/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,6 @@ export const enum Algorithm {
EdDSA = 11
}

export interface Claims {
data?: Record<string, any>
aud?: string
exp?: number
iat?: number
iss?: string
jti?: string
nbf?: number
sub?: string
}

export interface Header {
/**
* The algorithm used
Expand Down Expand Up @@ -96,9 +85,9 @@ export interface Header {
x5TS256CertThumbprint?: string
}

export function sign(claims: Claims, key: string | Buffer, header?: Header | undefined | null, abortSignal?: AbortSignal | undefined | null): Promise<string>
export function sign(claims: { [key: string]: any }, key: string | Buffer, header?: Header | undefined | null, abortSignal?: AbortSignal | undefined | null): Promise<string>

export function signSync(claims: Claims, key: string | Buffer, header?: Header | undefined | null): string
export function signSync(claims: { [key: string]: any }, key: string | Buffer, header?: Header | undefined | null): string

export interface Validation {
/**
Expand Down
10 changes: 7 additions & 3 deletions packages/jsonwebtoken/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,14 +323,18 @@ switch (platform) {
if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) {
try {
nativeBinding = require('./jsonwebtoken.wasi.cjs')
} catch {
// ignore
} catch (err) {
if (process.env.NAPI_RS_FORCE_WASI) {
console.error(err)
}
}
if (!nativeBinding) {
try {
nativeBinding = require('@node-rs/jsonwebtoken-wasm32-wasi')
} catch (err) {
console.error(err)
if (process.env.NAPI_RS_FORCE_WASI) {
console.error(err)
}
}
}
}
Expand Down
65 changes: 3 additions & 62 deletions packages/jsonwebtoken/src/claims.rs
Original file line number Diff line number Diff line change
@@ -1,63 +1,4 @@
use napi_derive::napi;
use serde::{Deserialize, Serialize};
use serde_json::{Map, Number, Value};
use indexmap::IndexMap;
use serde_json::Value;

#[napi(object)]
#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<Map<String, Value>>,
// Recipient for which the JWT is intended
#[serde(skip_serializing_if = "Option::is_none")]
pub aud: Option<String>,
// Time after which the JWT expires (as UTC timestamp, seconds from epoch time)
#[serde(skip_serializing_if = "Option::is_none")]
pub exp: Option<Number>,
// Time at which the JWT was issued (as UTC timestamp, seconds from epoch time)
#[serde(skip_serializing_if = "Option::is_none")]
pub iat: Option<Number>,
// Issuer of JWT
#[serde(skip_serializing_if = "Option::is_none")]
pub iss: Option<String>,
// [JWT id] Unique identifier
#[serde(skip_serializing_if = "Option::is_none")]
pub jti: Option<String>,
// [not-before-time] Time before which the JWT must not be accepted for processing (as UTC timestamp, seconds from epoch time)
#[serde(skip_serializing_if = "Option::is_none")]
pub nbf: Option<Number>,
// Subject of JWT (the user)
#[serde(skip_serializing_if = "Option::is_none")]
pub sub: Option<String>,
}

impl Claims {
#[inline]
pub fn merge(self, other: Self) -> Self {
Self {
data: self.data,
aud: self.aud.or(other.aud),
exp: self.exp.or(other.exp),
iat: self.iat.or(other.iat),
iss: self.iss.or(other.iss),
jti: self.jti.or(other.jti),
nbf: self.nbf.or(other.nbf),
sub: self.sub.or(other.sub),
}
}
}

impl Default for Claims {
#[inline]
fn default() -> Self {
Self {
data: Some(Map::new()),
aud: None,
exp: None,
iat: Some(jsonwebtoken::get_current_timestamp().into()),
iss: None,
jti: None,
nbf: None,
sub: None,
}
}
}
pub type Claims = IndexMap<String, Value>;
18 changes: 14 additions & 4 deletions packages/jsonwebtoken/src/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,18 +98,22 @@ impl Task for SignTask {

#[napi]
pub fn sign(
claims: Claims,
#[napi(ts_arg_type = "{ [key: string]: any }")] mut claims: Claims,
key: Either<String, JsBuffer>,
header: Option<Header>,
abort_signal: Option<AbortSignal>,
) -> Result<AsyncTask<SignTask>> {
if !claims.contains_key("iat") {
claims.insert("iat".parse()?, jsonwebtoken::get_current_timestamp().into());
}

Ok(AsyncTask::with_optional_signal(
SignTask {
header: match header {
Some(h) => h.merge(Header::default()),
_ => Header::default(),
},
claims: claims.merge(Claims::default()),
claims,
key: AsyncKeyInput::from_either(key)?,
},
abort_signal,
Expand All @@ -118,15 +122,21 @@ pub fn sign(

#[napi]
pub fn sign_sync(
claims: Claims,
#[napi(ts_arg_type = "{ [key: string]: any }")] mut claims: Claims,
key: Either<String, Buffer>,
header: Option<Header>,
) -> Result<String> {
if !claims.contains_key("iat") {
claims.insert(
"iat".to_owned(),
jsonwebtoken::get_current_timestamp().into(),
);
}

let header = match header {
Some(h) => h.merge(Header::default()),
_ => Header::default(),
};
let claims = claims.merge(Claims::default());

SignTask::sign(&claims, &header, key.as_ref())
}

0 comments on commit 89f2ce3

Please sign in to comment.