Skip to content

Commit

Permalink
Ensure required claims applies to custom claims (#423)
Browse files Browse the repository at this point in the history
  • Loading branch information
kieranm authored Feb 15, 2024
1 parent a77640f commit 3409d1d
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 13 deletions.
15 changes: 10 additions & 5 deletions src/verifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,18 +210,23 @@ function verifyToken(
// Verify the payload
const now = clockTimestamp || Date.now()

if (requiredClaims) {
for (const claim of requiredClaims) {
if (!(claim in payload)) {
throw new TokenError(TokenError.codes.missingRequiredClaim, `The ${claim} claim is required.`)
}
}
}

for (const validator of validators) {
const { type, claim, allowed, array, modifier, greater, errorCode, errorVerb } = validator
const value = payload[claim]
const arrayValue = Array.isArray(value)
const values = arrayValue ? value : [value]

// Check if the claim is marked as required before skipping it
// We have already checked above that all required claims are present
// Therefore we can skip this validator if the claim is not present
if (!(claim in payload)) {
if (requiredClaims && requiredClaims.includes(claim)) {
throw new TokenError(TokenError.codes.missingRequiredClaim, `The ${claim} claim is required.`)
}

continue
}

Expand Down
43 changes: 35 additions & 8 deletions test/verifier.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,11 @@ function verify(token, options, callback) {
test('it gets the correct decoded jwt token as argument on the key callback', async t => {
verify('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoxfQ.57TF7smP9XDhIexBqPC-F1toZReYZLWb_YRU5tv0sxM', {
key: async decoded => {
t.strictSame(
decoded,
{
header: { typ: 'JWT', alg: 'HS256' },
payload: { a: 1 },
signature: '57TF7smP9XDhIexBqPC-F1toZReYZLWb_YRU5tv0sxM'
}
)
t.strictSame(decoded, {
header: { typ: 'JWT', alg: 'HS256' },
payload: { a: 1 },
signature: '57TF7smP9XDhIexBqPC-F1toZReYZLWb_YRU5tv0sxM'
})

return Buffer.from('secret', 'utf-8')
},
Expand Down Expand Up @@ -957,6 +954,36 @@ test('it validates whether a required claim is present in the payload or not', t
t.end()
})

test('it validates whether a required custom claim is present in the payload or not', t => {
// Token payload: {"iss": "ISS", "custom": "custom", "iat": 1708023956}
const token =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJJU1MiLCJjdXN0b20iOiJjdXN0b20iLCJpYXQiOjE3MDgwMjQxMTh9.rD9GaHxuSB7mPkVQ2shj4yqPsvEuXWByMDNhMoch0xY'

t.strictSame(verify(token, { requiredClaims: ['iss', 'custom'] }), {
iss: 'ISS',
custom: 'custom',
iat: 1708024118
})

// Standard claim not covered by other validators
t.throws(
() => {
return verify(token, { requiredClaims: ['kid'] })
},
{ message: 'The kid claim is required.' }
)

// Custom claim
t.throws(
() => {
return verify(token, { requiredClaims: ['customTwo'] })
},
{ message: 'The customTwo claim is required.' }
)

t.end()
})

test("it skips validation when an allowed claim isn't present in the payload", t => {
// Token payload: { "iss": "ISS"}
const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJJU1MifQ.FKjJd2A-T8ufN7Y0LpjMR23P7CwEQ3Y-LBIYd2Vh_Rs'
Expand Down

0 comments on commit 3409d1d

Please sign in to comment.