-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Open
Description
Description
The callback to jwt.sign() is executed twice when there is an error Bad "options.issuer" option. The payload already has an "iss" property. I would expect the callback to only be executed once.
Reproduction
// a.mjs
import jwt from "jsonwebtoken";
jwt.sign(
{
iss: "bar",
iat: 1757476476,
},
"secret",
{
algorithm: "HS256",
issuer: "foo",
},
(err, asyncSigned) => {
console.log("callback called:", asyncSigned ?? err?.message);
},
);$> npm init -y && npm add jsonwebtoken
$> node a.mjs
callback called: Bad "options.issuer" option. The payload already has an "iss" property.
callback called: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJiYXIiLCJpYXQiOjE3NTc0NzY0NzZ9.TkSecbZDocHnjwnuDhQRXNvRkxsERNGBkRc6P0wHlNY
Notice that "callback called" is printed twice, while I would expect it to be printed only once.
Environment
jsonwebtoken 9.0.2 on Darwin 24.6.0 arm64 arm
Other information
It looks like the error is here:
Lines 217 to 225 in bc28861
| Object.keys(options_to_payload).forEach(function (key) { | |
| const claim = options_to_payload[key]; | |
| if (typeof options[key] !== 'undefined') { | |
| if (typeof payload[claim] !== 'undefined') { | |
| return failure(new Error('Bad "options.' + key + '" option. The payload already has an "' + claim + '" property.')); | |
| } | |
| payload[claim] = options[key]; | |
| } | |
| }); |
Typically, return failure() throws which exits the forEach and the function. But when a callback is provided, it only returns from the forEach. The rest of the keys are checked and the rest of the function still runs.
Metadata
Metadata
Assignees
Labels
No labels