英文:
jsonwebtoken 9.0.0 - getting error: TypeError: Cannot redefine property: decode - when trying to stub
问题
npm audit
刚刚发现 jsonwebtoken 存在安全漏洞。解决方案 是升级到版本 9.0.0
- 我已经这样做了。
然而,我的 mocha 测试现在无法通过。在 beforeEach
中,我试图使用 sinon.stub
来存根 decode
函数,但现在抛出以下 TypeError:
TypeError: 无法重新定义属性: decode
beforeEach 代码段如下:
const jwt = require('jsonwebtoken');
beforeEach(function () {
this.sinon.stub(jwt, 'verify').returns({ email: 'email@email.com' });
this.sinon.stub(jwt, 'decode').returns({ header: { alg: 'RS256', typ: 'JWT', kid: 'MOCKKID' } });
this.sinon.stub(jwks, 'getKey').returns('some mock certificate');
this.sinon.stub(T, 'expired');
});
我假设存根 verify
仍然有效,因为错误仅在下一行尝试存根 decode
时抛出。
是的,有一个类似问题的帖子,但它已经两年了,被接受的答案是“这很快会在未来版本中修复”。所以不太相关了。
英文:
so npm audit
just found jsonwebtoken to have a security vulnerbility. The solution is to update to version 9.0.0
- which I did.
However, my mocha tests are not passing now. During a beforeEach
, I am trying to stub the decode
function using sinon.stub
, which now throws this TypeError:
TypeError: Cannot redefine property: decode
The beforeEach:
const jwt = require('jsonwebtoken');
beforeEach(function () {
this.sinon.stub(jwt, 'verify').returns({ email: 'email@email.com' });
this.sinon.stub(jwt, 'decode').returns({ header: { alg: 'RS256', typ: 'JWT', kid: 'MOCKKID' } });
this.sinon.stub(jwks, 'getKey').returns('some mock certificate');
this.sinon.stub(T, 'expired');
});
I assume that stubbing verify
still works, since the error only throws on the next line when I try to stub decode
Yes, there is a post with similar question, but it's two years old, and the accepted answer is that "this is soon to be fixed in a future version". So not really relevant anymore.
答案1
得分: 3
因为jsonwebtoken
v9.0.0将decode
函数设置为不可枚举和不可配置,请参见v9.0.0/index.js#L9
index.js
:
module.exports = {
verify: require('./verify'),
sign: require('./sign'),
JsonWebTokenError: require('./lib/JsonWebTokenError'),
NotBeforeError: require('./lib/NotBeforeError'),
TokenExpiredError: require('./lib/TokenExpiredError'),
};
Object.defineProperty(module.exports, 'decode', {
enumerable: false,
value: require('./decode'),
});
根据文档Object.defineProperty创建的不可配置属性
如果您未将其配置为可配置属性,则
Object.defineProperty()
将创建不可配置属性。
这意味着configurable: false
是默认值。这就是为什么sinon.stub(jwt, 'decode')
不再起作用的原因。
并且有一个PR试图修复它以允许对decode
函数进行存根。该PR将decode
设置为可配置:
Object.defineProperty(module.exports, 'decode', {
enumerable: false,
configurable: true,
value: require('./decode'),
});
有一个临时解决方案,您可以创建自己的jwt工具模块并对自己的jwt工具进行存根。
例如:
jwt-repack.js
:
const jwt = require('jsonwebtoken');
const decode = require('jsonwebtoken').decode;
module.exports = {
...jwt,
decode
};
index.test.js
:
const sinon = require('sinon');
const jwt = require('./jwt-repack');
it('should pass', () => {
sinon.stub(jwt, 'decode').returns({ header: { alg: 'RS256', typ: 'JWT', kid: 'MOCKKID' } });
const actual = jwt.decode();
sinon.assert.match(actual, { header: { alg: 'RS256', typ: 'JWT', kid: 'MOCKKID' } });
});
包版本:
"jsonwebtoken9": "npm:jsonwebtoken@^9.0.0",
"sinon": "^8.1.1",
英文:
Because jsonwebtoken
v9.0.0 makes the decode
function non-enumerable and non-configurable, see v9.0.0/index.js#L9
index.js
:
module.exports = {
verify: require('./verify'),
sign: require('./sign'),
JsonWebTokenError: require('./lib/JsonWebTokenError'),
NotBeforeError: require('./lib/NotBeforeError'),
TokenExpiredError: require('./lib/TokenExpiredError'),
};
Object.defineProperty(module.exports, 'decode', {
enumerable: false,
value: require('./decode'),
});
From the documentation Non-configurable properties created by Object.defineProperty
> The Object.defineProperty()
creates non-configurable properties if you haven't specified them as configurable.
Which means the configurable: false
is the default. That's why sinon.stub(jwt, 'decode')
doesn't work anymore.
And there is PR trying to fix it to allow the decode
function to be stubbed. This PR makes the decode
configurable:
Object.defineProperty(module.exports, 'decode', {
enumerable: false,
configurable: true,
value: require('./decode'),
});
There is a temporary solution, you can create your own jwt utils module and stub your own jwt utils.
E.g.
jwt-repack.js
:
const jwt = require('jsonwebtoken');
const decode = require('jsonwebtoken').decode;
module.exports = {
...jwt,
decode
};
index.test.js
:
const sinon = require('sinon');
const jwt = require('./jwt-repack');
it('should pass', () => {
sinon.stub(jwt, 'decode').returns({ header: { alg: 'RS256', typ: 'JWT', kid: 'MOCKKID' } });
const actual = jwt.decode();
sinon.assert.match(actual, { header: { alg: 'RS256', typ: 'JWT', kid: 'MOCKKID' } });
});
package versions:
"jsonwebtoken9": "npm:jsonwebtoken@^9.0.0",
"sinon": "^8.1.1",
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论