-
Notifications
You must be signed in to change notification settings - Fork 39
Closed
Labels
bugSomething isn't workingSomething isn't workingjavascriptPull requests that update Javascript codePull requests that update Javascript code
Description
Description
There is an issue in fast-jwt
where the exp
, nbf
, and iat
claims are incorrectly calculated when expiresIn
is provided in seconds. Specifically, the issue arises when payload.iat
is in milliseconds, but expiresIn
is in seconds, which results in incorrect expiration calculations.
Steps to Reproduce
- Create a JWT with
expiresIn
in seconds. - Ensure that
payload.iat
is set (or not set) and potentially in milliseconds. - Observe that the
exp
andnbf
values are incorrectly calculated ifiat
is in milliseconds.
Expected Behavior
- The
exp
,nbf
, andiat
claims should all be calculated correctly with consistent units (typically in seconds). - The calculation should correctly handle cases where
iat
is in milliseconds.
Actual Behavior
- When
payload.iat
is in milliseconds, andexpiresIn
is given in seconds, theexp
(expiration) andnbf
(not before) values are incorrectly calculated due to a mismatch in units.
Code Snippet
The issue is occurring in the following code:
const finalPayload = {
...payload,
...fixedPayload,
iat: noTimestamp ? undefined : Math.floor(iat / 1000), // this line
exp: payload.exp ? payload.exp : expiresIn ? Math.floor((iat + expiresIn) / 1000) : undefined, // this line
nbf: payload.nbf ? payload.nbf : notBefore ? Math.floor((iat + notBefore) / 1000) : undefined // this line
}
Suggested Fix
- To solve the issue of inconsistent timestamp units, the
iat
should be converted to seconds before performing calculations forexp
andnbf
. Here’s the corrected solution:
const iat = payload.iat * 1000 || clockTimestamp || Date.now(); // Handle `iat` in milliseconds
const iatSec = (iat / 1000); // Convert `iat` to seconds
const finalPayload = {
...payload,
...fixedPayload,
iat: noTimestamp ? undefined : Math.floor(iatSec),
exp: payload.exp ? payload.exp : expiresIn ? Math.floor(iatSec + expiresIn) : undefined,
nbf: payload.nbf ? payload.nbf : notBefore ? Math.floor(iatSec + notBefore) : undefined
}
Explanation:
iat
is originally in milliseconds (as it's calculated byDate.now()
), so it is first converted to seconds (iatSec
).- The
exp
(expiration) andnbf
(not before) are then calculated usingiatSec
, ensuring all timestamp calculations are in seconds. - This fix resolves the inconsistency in units between
expiresIn
(in seconds) andiat
(in milliseconds).
Environment
fast-jwt
version: 5.0.5Node.js
version: v20.9.0- OS: Windows X64
Additional Information
- The issue may not be immediately apparent unless the
iat
is not manually set and theexpiresIn
is in seconds. - This issue leads to incorrect expiration times if the
iat
is in milliseconds.
Link to Source Code
You can find the relevant code in the fast-jwt
repository here: fast-jwt Signer.js - Line 93.
dosubot
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingjavascriptPull requests that update Javascript codePull requests that update Javascript code