Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chore/code improvements #509

Merged
merged 12 commits into from
Nov 15, 2024
78 changes: 31 additions & 47 deletions src/verifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,17 @@ function exactStringClaimMatcher(allowed, actual) {
}

function checkAreCompatibleAlgorithms(expected, actual) {
let valid = false

for (const expectedAlg of expected) {
valid = actual.indexOf(expectedAlg) !== -1

// if at least one of the expected algorithms is compatible we're done
if (valid) {
break
if (actual.includes(expectedAlg)) {
return
}
}

if (!valid) {
throw new TokenError(
TokenError.codes.invalidKey,
`Invalid public key provided for algorithms ${expected.join(', ')}.`
)
}
throw new TokenError(
TokenError.codes.invalidKey,
`Invalid public key provided for algorithms ${expected.join(', ')}.`
)
}

function prepareKeyOrSecret(key, isSecret) {
Expand Down Expand Up @@ -72,7 +66,7 @@ function cacheSet(
ignoreExpiration,
ignoreNotBefore,
maxAge,
clockTimestamp,
clockTimestamp = Date.now(),
clockTolerance,
errorCacheTTL
},
Expand All @@ -86,7 +80,7 @@ function cacheSet(

if (value instanceof TokenError) {
const ttl = typeof errorCacheTTL === 'function' ? errorCacheTTL(value) : errorCacheTTL
cacheValue[2] = (clockTimestamp || Date.now()) + clockTolerance + ttl
cacheValue[2] = clockTimestamp + clockTolerance + ttl
cache.set(hashToken(token), cacheValue)
return value
}
Expand All @@ -107,7 +101,7 @@ function cacheSet(
}

// The maximum TTL for the token cannot exceed the configured cacheTTL
const maxTTL = (clockTimestamp || Date.now()) + clockTolerance + cacheTTL
const maxTTL = clockTimestamp + clockTolerance + cacheTTL
cacheValue[2] = cacheValue[2] === 0 ? maxTTL : Math.min(cacheValue[2], maxTTL)

cache.set(hashToken(token), cacheValue)
Expand Down Expand Up @@ -135,10 +129,8 @@ function handleCachedResult(cached, callback, promise) {

function validateAlgorithmAndSignature(input, header, signature, key, allowedAlgorithms) {
// According to the signature and key, check with algorithms are supported
const algorithms = allowedAlgorithms

// Verify the token is allowed
if (!algorithms.includes(header.alg)) {
if (!allowedAlgorithms.includes(header.alg)) {
throw new TokenError(TokenError.codes.invalidAlgorithm, 'The token algorithm is invalid.')
}

Expand Down Expand Up @@ -180,7 +172,7 @@ function validateClaimDateValue(value, modifier, now, greater, errorCode, errorV
function verifyToken(
key,
{ input, header, payload, signature },
{ validators, allowedAlgorithms, checkTyp, clockTimestamp, clockTolerance, requiredClaims }
{ validators, allowedAlgorithms, checkTyp, clockTimestamp, requiredClaims }
) {
// Verify the key
/* istanbul ignore next */
Expand All @@ -195,15 +187,10 @@ function verifyToken(
validateAlgorithmAndSignature(input, header, signature, key, allowedAlgorithms)

// Verify typ
if (checkTyp) {
if (typeof header.typ !== 'string' || checkTyp !== header.typ.toLowerCase().replace(/^application\//, '')) {
throw new TokenError(TokenError.codes.invalidType, 'Invalid typ.')
}
if (checkTyp && (typeof header.typ !== 'string' || checkTyp !== header.typ.toLowerCase().replace(/^application\//, ''))) {
throw new TokenError(TokenError.codes.invalidType, 'Invalid typ.')
}

// Verify the payload
const now = clockTimestamp || Date.now()

if (requiredClaims) {
for (const claim of requiredClaims) {
if (!(claim in payload)) {
Expand All @@ -212,8 +199,10 @@ function verifyToken(
}
}

for (const validator of validators) {
const { type, claim, allowed, array, modifier, greater, errorCode, errorVerb } = validator
// Verify the payload
const now = clockTimestamp || Date.now()

for (const { type, claim, allowed, array, modifier, greater, errorCode, errorVerb } of validators) {
const value = payload[claim]
const arrayValue = Array.isArray(value)
const values = arrayValue ? value : [value]
Expand Down Expand Up @@ -259,19 +248,6 @@ function verify(
) {
const [callback, promise] = isAsync ? ensurePromiseCallback(cb) : []

const cacheContext = {
cache,
token,
cacheTTL,
errorCacheTTL,
payload: undefined,
ignoreExpiration,
ignoreNotBefore,
maxAge,
clockTimestamp,
clockTolerance
}

// Check the cache
if (cache) {
const [value, min, max] = cache.get(hashToken(token)) || [undefined, 0, 0]
Expand Down Expand Up @@ -308,7 +284,18 @@ function verify(
}

const { header, payload, signature } = decoded
cacheContext.payload = payload
const cacheContext = {
cache,
token,
cacheTTL,
errorCacheTTL,
ignoreExpiration,
ignoreNotBefore,
maxAge,
clockTimestamp,
clockTolerance,
payload
}
const validationContext = { validators, allowedAlgorithms, checkTyp, clockTimestamp, clockTolerance, requiredClaims }

// We have the key
Expand Down Expand Up @@ -387,7 +374,7 @@ module.exports = function createVerifier(options) {
allowedSub,
allowedNonce,
requiredClaims
} = { cacheTTL: 600000, clockTolerance: 0, errorCacheTTL: -1, ...options }
} = { cacheTTL: 600_000, clockTolerance: 0, errorCacheTTL: -1, ...options }

// Validate options
if (!Array.isArray(allowedAlgorithms)) {
Expand Down Expand Up @@ -489,10 +476,7 @@ module.exports = function createVerifier(options) {
validators.push({ type: 'string', claim: 'nonce', allowed: ensureStringClaimMatcher(allowedNonce) })
}

let normalizedTyp = null
if (checkTyp) {
normalizedTyp = checkTyp.toLowerCase().replace(/^application\//, '')
}
const normalizedTyp = checkTyp ? checkTyp.toLowerCase().replace(/^application\//, '') : null

const context = {
key,
Expand Down
Loading