claims with arrays cause a stringified payload to be created, rather than an object
chrisnurse opened this issue · 8 comments
Note below that roles and permissions are arrays. If either has more than one element, the entire payload becomes stringified:
// Run this and paste the token into the debugger at jwt.io, you will observe a stringified payload
auth_token = auth.GetToken({
return {
nickname: "jest.jester",
name: "jest@itest.com",
updated_at: "2022-10-09T11:36:37.582Z",
email: "jest@itest.com",
iss: `${domain}/`,
sub: "auth0|633c191bd579670011607e98",
aud: "TWqR7DTIezpfW82qXFt0lchMXixIpFLQ",
iat: 1665315399,
exp: 5665351399,
sid: "lBZb4EUN7LpXu7Urp-lRQ3qnCzDVBf23",
nonce: "RzZtVlVTT1dqZ1lvWFpSYzFnbnB2RXZkdWcuNDJQRkREUH5KMUVJNWdMSA==",
permissions: ["read_all"],
roles: ["admin", "leader"]
};
}
When only one element appears in the arrays, all is well
// Run this and paste the token into the debugger at jwt.io, you will observe a stringified payload
auth_token = auth.GetToken({
return {
nickname: "jest.jester",
name: "jest@itest.com",
updated_at: "2022-10-09T11:36:37.582Z",
email: "jest@itest.com",
iss: `${domain}/`,
sub: "auth0|633c191bd579670011607e98",
aud: "TWqR7DTIezpfW82qXFt0lchMXixIpFLQ",
iat: 1665315399,
exp: 5665351399,
sid: "lBZb4EUN7LpXu7Urp-lRQ3qnCzDVBf23",
nonce: "RzZtVlVTT1dqZ1lvWFpSYzFnbnB2RXZkdWcuNDJQRkREUH5KMUVJNWdMSA==",
permissions: ["read_all"],
roles: ["admin"]
};
}
** JWT.io **
Hey @chrisnurse! Thank you for finding this. Would you be able to write a test for this? You would have to fork this repo and add a test, push it to your fork and then open a PR here. You might even add the fix, but if that does not work, I can take a look. But writing the test should be doable and would help me a lot.
I tried to reproduce and failed. Unfortunately your code example is quite incomplete. It looks like "auth.GetToken" is a function or rather method written by you. I cannot say what this function does. Until you provide the full code, I fear I cannot work on this, because I would have to wildly guess what is going on. Also maybe the problem occurs when you copy the token? Closing this until further information is provided.
The auth.Gettoken simply wraps the jwks.getToken. I appreciate it's hard as none of these things happen in isolation :)
I'm a bit time poor, so what I suggest is you take this test code and remove the couple of lines that use my wrapper....
test("creates and decodes a valid token", async () => {
const auth = new AuthMock(domain, true);
const claims = {
nickname: "jest.jester",
name: "jest@itest.com",
updated_at: "2022-10-09T11:36:37.582Z",
email: "jest@itest.com",
iss: "https://jest.au.auth0.com/",
sub: "auth0|633c191bd579670011607e98",
aud: "TWqR7DTIezpfW82qXFt0lchMXixIpFLQ",
iat: 1665315399,
exp: 5665351399,
sid: "lBZb4EUN7LpXu7Urp-lRQ3qnCzDVBf23",
nonce: "RzZtVlVTT1dqZ1lvWFpSYzFnbnB2RXZkdWcuNDJQRkREUH5KMUVJNWdMSA==",
roles: [
"admin",
],
permissions: [
"create:all",
"read:all",
"write:all",
"update:all",
"delete:all",
],
}
const token = auth.GetToken(claims);
const decoded = await auth.VerifyToken(token);
expect(decoded.name).toEqual(admin_claims.name);
expect(decoded.permissions.includes("delete:all")).toBe(true);
});
I am sure you get the gist...just copy my claims object and inject it into your getToken method, which is what I do just using my wrapper method is all. The test will run to completion. The issue isn't that this test doesn't work. Specifically, the issue is if you set a breakpoint so you can copy the encoded token to the clipboard, then go paste it in at JWT.io, it will appear stringified, even though in the test it appears correctly decoded.
What I infer from this is that, mock-jwks can encode and decode its own token, but when passed through the auth0 library express-oauth2-jwt-bearer the payload apears there and at JWT.io in the wrong format.
Here is the encoded token returned from mock-jwks. Copy and paste it into the debugger at JWT.io and you will see what I see...
eyJhbGciOiJSUzI1NiIsImtpZCI6Illra3pOamsxTWtabWMybFZVMUJ5WmtZNWMySjFUbFU1VUROalBRIn0.eyJuaWNrbmFtZSI6Implc3QuamVzdGVyIiwibmFtZSI6Implc3RAaXRlc3QuY29tIiwidXBkYXRlZF9hdCI6IjIwMjItMTAtMDlUMTE6MzY6MzcuNTgyWiIsImVtYWlsIjoiamVzdEBpdGVzdC5jb20iLCJpc3MiOiJodHRwczovL2plc3QuYXUuYXV0aDAuY29tLyIsInN1YiI6ImF1dGgwfDYzM2MxOTFiZDU3OTY3MDAxMTYwN2U5OCIsImF1ZCI6IlRXcVI3RFRJZXpwZlc4MnFYRnQwbGNoTVhpeElwRkxRIiwiaWF0IjoxNjY1MzE1Mzk5LCJleHAiOjU2NjUzNTEzOTksInNpZCI6ImxCWmI0RVVON0xwWHU3VXJwLWxSUTNxbkN6RFZCZjIzIiwibm9uY2U…SRVVINUtNVVZKTldkTVNBPT0iLCJyb2xlcyI6WyJhZG1pbiJdLCJwZXJtaXNzaW9ucyI6WyJjcmVhdGU6YWxsIiwicmVhZDphbGwiLCJ3cml0ZTphbGwiLCJ1cGRhdGU6YWxsIiwiZGVsZXRlOmFsbCJdfQ.FyPEARrNZlAia7zpo8viZd4zqjzY10msSNyKOmwf27Du-CnKwWMpyUeiAS2nvxYP-QPvSKp6xRNFwC1fO0GYpHHhPd0d6uhuWwSFOWPBYs6v4CXxiBAvQBiVhCwCbqpKrd8xbaaCMbvq2_IsaJGNddWm0K4aCf6SmWogTLH_GDOL5jrNg1gl2iKRi3WnbTe_aiq5d1UI5UYfqWfc40DwFY3YMa-QuVmbO8sg50jsTCOVTfrRzZklGo3hZq6ivgm8TZ7s6igwrJjEz90mNI3sjgJJDeyfusB8V99L4avbfVznY-fywyRTK7VivQXyd3K9QdvCsEz2HEbE33-EFDcA
Cheers,
Chris
Taking a look.
I greatly appreciate the rapid response and effort here.
I'm not sure from the above comments if you found and fixed the issue?
Can I do anything else to support?
Hi - once again thank you for your responsiveness and support.
I have forked the repo and created tests with more complex claims and can not reproduce my stringification issue.
I did note errors in my configuration, including variables for audience/issuer.
In order to share additional tests with more complex examples of claims, I will create a PR for your consideration. Sorry, the PR process is new to me, so I am currently cleaning up copy/paste and linting issues.
Apologies for consuming so much time with this issue.
I thank you for putting in all this effort. It is important to investigate and see if an error only affects yourself or every user of the package. So I think this was very much worth while. I will have a look at your PR and see why it fails. Please have a look at the changes from #80 Your remarks made me realise that the current implementation of sign
was too complicated and also buggy. So I fixed that and as a side effect to not use Buffer
or JSON.stringify
any more. I will release these changes with 1.0.6 in a minute.
Closing this issue as not reproducible.