diff --git a/sign.js b/sign.js index 82bf526..f5ac5d8 100644 --- a/sign.js +++ b/sign.js @@ -214,7 +214,7 @@ module.exports = function (payload, secretOrPrivateKey, options, callback) { } } - Object.keys(options_to_payload).forEach(function (key) { + for (const key of Object.keys(options_to_payload)) { const claim = options_to_payload[key]; if (typeof options[key] !== 'undefined') { if (typeof payload[claim] !== 'undefined') { @@ -222,7 +222,7 @@ module.exports = function (payload, secretOrPrivateKey, options, callback) { } payload[claim] = options[key]; } - }); + }; const encoding = options.encoding || 'utf8'; diff --git a/test/callback-issue.test.js b/test/callback-issue.test.js new file mode 100644 index 0000000..5c519c1 --- /dev/null +++ b/test/callback-issue.test.js @@ -0,0 +1,24 @@ +const assert = require('assert'); +const jwt = require('../index.js'); + +describe('Fix: jwt.sign callback should not be called twice', function () { + it('should call callback only once when payload.iss conflicts with options.issuer', function (done) { + let callbackCount = 0; + + jwt.sign( + { iss: 'bar', iat: 1757476476 }, + 'secret', + { algorithm: 'HS256', issuer: 'foo' }, + (err) => { + callbackCount++; + assert.ok(err, 'Expected an error due to issuer conflict'); + assert.strictEqual( + err.message, + 'Bad "options.issuer" option. The payload already has an "iss" property.' + ); + assert.strictEqual(callbackCount, 1, 'Callback was called more than once'); + done(); + } + ); + }); +});