From dae254fa885758d2bafce39efdc1a5173f417fa3 Mon Sep 17 00:00:00 2001 From: Matteo Pietro Dazzi Date: Sun, 10 Nov 2024 10:14:36 +0100 Subject: [PATCH] feat: LRU cache key --- src/utils.js | 17 --------- src/verifier.js | 8 ++--- test/verifier.spec.js | 83 ++++++++++++++++++++----------------------- 3 files changed, 43 insertions(+), 65 deletions(-) diff --git a/src/utils.js b/src/utils.js index 4f0ec42..c17d6f3 100644 --- a/src/utils.js +++ b/src/utils.js @@ -42,24 +42,7 @@ function ensurePromiseCallback(callback) { ] } -function hashToken(token) { - const rawHeader = token.split('.', 1)[0] - const header = Buffer.from(rawHeader, 'base64').toString('utf-8') - let hasher = null - - /* istanbul ignore next */ - if (header.match(edAlgorithmMatcher) && header.match(ed448CurveMatcher)) { - hasher = createHash('shake256', { outputLength: 114 }) - } else { - const mo = header.match(algorithmMatcher) - hasher = createHash(`sha${mo ? mo[1] : '512'}`) - } - - return hasher.update(token).digest('hex') -} - module.exports = { getAsyncKey, ensurePromiseCallback, - hashToken } diff --git a/src/verifier.js b/src/verifier.js index 3a6078e..42bc18a 100644 --- a/src/verifier.js +++ b/src/verifier.js @@ -6,7 +6,7 @@ const Cache = require('mnemonist/lru-cache') const { useNewCrypto, hsAlgorithms, verifySignature, detectPublicKeyAlgorithms } = require('./crypto') const createDecoder = require('./decoder') const { TokenError } = require('./error') -const { getAsyncKey, ensurePromiseCallback, hashToken } = require('./utils') +const { getAsyncKey, ensurePromiseCallback } = require('./utils') const defaultCacheSize = 1000 @@ -93,7 +93,7 @@ function cacheSet( if (value instanceof TokenError) { const ttl = typeof errorCacheTTL === 'function' ? errorCacheTTL(value) : errorCacheTTL cacheValue[2] = (clockTimestamp || Date.now()) + clockTolerance + ttl - cache.set(hashToken(token), cacheValue) + cache.set(token, cacheValue) return value } @@ -116,7 +116,7 @@ function cacheSet( const maxTTL = (clockTimestamp || Date.now()) + clockTolerance + cacheTTL cacheValue[2] = cacheValue[2] === 0 ? maxTTL : Math.min(cacheValue[2], maxTTL) - cache.set(hashToken(token), cacheValue) + cache.set(token, cacheValue) return value } @@ -280,7 +280,7 @@ function verify( // Check the cache if (cache) { - const [value, min, max] = cache.get(hashToken(token)) || [undefined, 0, 0] + const [value, min, max] = cache.get(token) || [undefined, 0, 0] const now = clockTimestamp || Date.now() // Validate time range diff --git a/test/verifier.spec.js b/test/verifier.spec.js index b365d8a..ec7a603 100644 --- a/test/verifier.spec.js +++ b/test/verifier.spec.js @@ -8,7 +8,6 @@ const { install: fakeTime } = require('@sinonjs/fake-timers') const { createSigner, createVerifier, TokenError } = require('../src') const { useNewCrypto } = require('../src/crypto') -const { hashToken } = require('../src/utils') const privateKeys = { HS: 'secretsecretsecret', @@ -1017,8 +1016,8 @@ test('caching - sync', t => { t.assert.throws(() => verifier(invalidToken), { message: 'The token signature is invalid.' }) t.assert.equal(verifier.cache.size, 2) - t.assert.deepStrictEqual(verifier.cache.get(hashToken(token))[0], { a: 1 }) - t.assert.ok(verifier.cache.get(hashToken(invalidToken))[0] instanceof TokenError) + t.assert.deepStrictEqual(verifier.cache.get(token)[0], { a: 1 }) + t.assert.ok(verifier.cache.get(invalidToken)[0] instanceof TokenError) }) test('caching - async', async t => { @@ -1038,8 +1037,8 @@ test('caching - async', async t => { await t.assert.rejects(async () => verifier(invalidToken), { message: 'The token signature is invalid.' }) t.assert.equal(verifier.cache.size, 2) - t.assert.deepStrictEqual(verifier.cache.get(hashToken(token))[0], { a: 1 }) - t.assert.ok(verifier.cache.get(hashToken(invalidToken))[0] instanceof TokenError) + t.assert.deepStrictEqual(verifier.cache.get(token)[0], { a: 1 }) + t.assert.ok(verifier.cache.get(invalidToken)[0] instanceof TokenError) }) for (const type of ['HS', 'ES', 'RS', 'PS']) { @@ -1053,11 +1052,9 @@ for (const type of ['HS', 'ES', 'RS', 'PS']) { const verifier = createVerifier({ algorithm, key: publicKey, cache: true }) const token = signer({ a: 1 }) - const hash = createHash(`sha${bits}`).update(token).digest('hex') - t.assert.deepStrictEqual(verifier(token), { a: 1 }) t.assert.equal(verifier.cache.size, 1) - t.assert.equal(Array.from(verifier.cache.keys())[0], hash) + t.assert.equal(Array.from(verifier.cache.keys())[0], token) }) } } @@ -1067,11 +1064,10 @@ if (useNewCrypto) { const signer = createSigner({ algorithm: 'EdDSA', key: privateKeys.Ed25519, noTimestamp: 1 }) const verifier = createVerifier({ key: publicKeys.Ed25519, cache: true }) const token = signer({ a: 1 }) - const hash = createHash('sha512').update(token).digest('hex') t.assert.deepStrictEqual(verifier(token), { a: 1 }) t.assert.equal(verifier.cache.size, 1) - t.assert.equal(Array.from(verifier.cache.keys())[0], hash) + t.assert.equal(Array.from(verifier.cache.keys())[0], token) }) test('caching - should use the right hash method for storing values - EdDSA with Ed448', t => { @@ -1083,11 +1079,10 @@ if (useNewCrypto) { }) const verifier = createVerifier({ key: publicKeys.Ed448, cache: true }) const token = signer({ a: 1 }) - const hash = createHash('shake256', { outputLength: 114 }).update(token).digest('hex') t.assert.deepStrictEqual(verifier(token), { a: 1 }) t.assert.equal(verifier.cache.size, 1) - t.assert.equal(Array.from(verifier.cache.keys())[0], hash) + t.assert.equal(Array.from(verifier.cache.keys())[0], token) }) } @@ -1101,7 +1096,7 @@ test('caching - should be able to manipulate cache directy', t => { t.assert.equal(verifier.cache.size, 0) t.assert.deepStrictEqual(verifier(token), { a: 1, iat: 100, exp: 200 }) t.assert.equal(verifier.cache.size, 1) - t.assert.deepStrictEqual(verifier.cache.get(hashToken(token)), [{ a: 1, iat: 100, exp: 200 }, 0, 200000]) + t.assert.deepStrictEqual(verifier.cache.get(token), [{ a: 1, iat: 100, exp: 200 }, 0, 200000]) verifier.cache.clear() t.assert.equal(verifier.cache.size, 0) verifier.cache.set(token, 'WHATEVER') @@ -1125,7 +1120,7 @@ test('caching - should correctly expire cached token using the exp claim', t => t.assert.equal(verifier.cache.size, 1) t.assert.deepStrictEqual(verifier(token), { a: 1, iat: 100, exp: 200 }) t.assert.equal(verifier.cache.size, 1) - t.assert.deepStrictEqual(verifier.cache.get(hashToken(token)), [{ a: 1, iat: 100, exp: 200 }, 0, 200000]) + t.assert.deepStrictEqual(verifier.cache.get(token), [{ a: 1, iat: 100, exp: 200 }, 0, 200000]) // Now advance to expired time clock.tick(200000) @@ -1133,7 +1128,7 @@ test('caching - should correctly expire cached token using the exp claim', t => // The token should now be expired and the cache should have been updated to reflect it t.assert.throws(() => verifier(token), { message: 'The token has expired at 1970-01-01T00:03:20.000Z.' }) t.assert.equal(verifier.cache.size, 1) - t.assert.ok(verifier.cache.get(hashToken(token))[0] instanceof TokenError) + t.assert.ok(verifier.cache.get(token)[0] instanceof TokenError) t.assert.throws(() => verifier(token), { message: 'The token has expired at 1970-01-01T00:03:20.000Z.' }) t.assert.throws(() => verifier(token), { message: 'The token has expired at 1970-01-01T00:03:20.000Z.' }) @@ -1144,12 +1139,12 @@ test('caching - should correctly expire cached token using the exp claim', t => verifier.cache.clear() t.assert.throws(() => verifier(token), { message: 'The token has expired at 1970-01-01T00:03:20.000Z.' }) t.assert.equal(verifier.cache.size, 1) - t.assert.ok(verifier.cache.get(hashToken(token))[0] instanceof TokenError) + t.assert.ok(verifier.cache.get(token)[0] instanceof TokenError) const verifierWithTimestamp = createVerifier({ key: 'secret', cache: true, clockTimestamp: 100000 }) t.assert.deepStrictEqual(verifierWithTimestamp(token), { a: 1, iat: 100, exp: 200 }) t.assert.equal(verifierWithTimestamp.cache.size, 1) - t.assert.deepStrictEqual(verifierWithTimestamp.cache.get(hashToken(token)), [{ a: 1, iat: 100, exp: 200 }, 0, 200000]) + t.assert.deepStrictEqual(verifierWithTimestamp.cache.get(token), [{ a: 1, iat: 100, exp: 200 }, 0, 200000]) }) test('caching - should correctly expire cached token using the maxAge claim', t => { @@ -1165,7 +1160,7 @@ test('caching - should correctly expire cached token using the maxAge claim', t t.assert.equal(verifier.cache.size, 1) t.assert.deepStrictEqual(verifier(token), { a: 1, iat: 100 }) t.assert.equal(verifier.cache.size, 1) - t.assert.deepStrictEqual(verifier.cache.get(hashToken(token)), [{ a: 1, iat: 100 }, 0, 200000]) + t.assert.deepStrictEqual(verifier.cache.get(token), [{ a: 1, iat: 100 }, 0, 200000]) // Now advance to expired time clock.tick(200000) @@ -1173,7 +1168,7 @@ test('caching - should correctly expire cached token using the maxAge claim', t // The token should now be expired and the cache should have been updated to reflect it t.assert.throws(() => verifier(token), { message: 'The token has expired at 1970-01-01T00:03:20.000Z.' }) t.assert.equal(verifier.cache.size, 1) - t.assert.ok(verifier.cache.get(hashToken(token))[0] instanceof TokenError) + t.assert.ok(verifier.cache.get(token)[0] instanceof TokenError) t.assert.throws(() => verifier(token), { message: 'The token has expired at 1970-01-01T00:03:20.000Z.' }) t.assert.throws(() => verifier(token), { message: 'The token has expired at 1970-01-01T00:03:20.000Z.' }) @@ -1192,7 +1187,7 @@ test('caching - should correctly expire not yet cached token using the nbf claim t.assert.throws(() => verifier(token), { message: 'The token will be active at 1970-01-01T00:05:00.000Z.' }) t.assert.equal(verifier.cache.size, 1) t.assert.throws(() => verifier(token), { message: 'The token will be active at 1970-01-01T00:05:00.000Z.' }) - t.assert.ok(verifier.cache.get(hashToken(token))[0] instanceof TokenError) + t.assert.ok(verifier.cache.get(token)[0] instanceof TokenError) // Now advance to expired time clock.tick(200000) @@ -1202,7 +1197,7 @@ test('caching - should correctly expire not yet cached token using the nbf claim t.assert.equal(verifier.cache.size, 1) t.assert.deepStrictEqual(verifier(token), { a: 1, iat: 100, nbf: 300 }) t.assert.equal(verifier.cache.size, 1) - t.assert.deepStrictEqual(verifier.cache.get(hashToken(token)), [{ a: 1, iat: 100, nbf: 300 }, 300000, 900000]) + t.assert.deepStrictEqual(verifier.cache.get(token), [{ a: 1, iat: 100, nbf: 300 }, 300000, 900000]) clock.uninstall() }) @@ -1219,7 +1214,7 @@ test('caching - should correctly expire not yet cached token using the nbf claim t.assert.throws(() => verifier(token), { message: 'The token will be active at 1970-01-01T00:05:00.000Z.' }) t.assert.equal(verifier.cache.size, 1) t.assert.throws(() => verifier(token), { message: 'The token will be active at 1970-01-01T00:05:00.000Z.' }) - t.assert.ok(verifier.cache.get(hashToken(token))[0] instanceof TokenError) + t.assert.ok(verifier.cache.get(token)[0] instanceof TokenError) // Now advance after expired time clock.tick(200010) @@ -1229,7 +1224,7 @@ test('caching - should correctly expire not yet cached token using the nbf claim t.assert.equal(verifier.cache.size, 1) t.assert.deepStrictEqual(verifier(token), { a: 1, iat: 100, nbf: 300 }) t.assert.equal(verifier.cache.size, 1) - t.assert.deepStrictEqual(verifier.cache.get(hashToken(token)), [{ a: 1, iat: 100, nbf: 300 }, 300000, 900010]) + t.assert.deepStrictEqual(verifier.cache.get(token), [{ a: 1, iat: 100, nbf: 300 }, 300000, 900010]) clock.uninstall() }) @@ -1246,7 +1241,7 @@ test('caching - should be able to consider both nbf and exp field at the same ti t.assert.throws(() => verifier(token), { message: 'The token will be active at 1970-01-01T00:05:00.000Z.' }) t.assert.equal(verifier.cache.size, 1) t.assert.throws(() => verifier(token), { message: 'The token will be active at 1970-01-01T00:05:00.000Z.' }) - t.assert.ok(verifier.cache.get(hashToken(token))[0] instanceof TokenError) + t.assert.ok(verifier.cache.get(token)[0] instanceof TokenError) // Now advance to activation time clock.tick(200000) @@ -1256,7 +1251,7 @@ test('caching - should be able to consider both nbf and exp field at the same ti t.assert.equal(verifier.cache.size, 1) t.assert.deepStrictEqual(verifier(token), { a: 1, iat: 100, nbf: 300, exp: 500 }) t.assert.equal(verifier.cache.size, 1) - t.assert.deepStrictEqual(verifier.cache.get(hashToken(token)), [{ a: 1, iat: 100, nbf: 300, exp: 500 }, 300000, 500000]) + t.assert.deepStrictEqual(verifier.cache.get(token), [{ a: 1, iat: 100, nbf: 300, exp: 500 }, 300000, 500000]) // Now advance again after the expiry time clock.tick(210000) @@ -1264,7 +1259,7 @@ test('caching - should be able to consider both nbf and exp field at the same ti // The token should now be expired and the cache should have been updated to reflect it t.assert.throws(() => verifier(token), { message: 'The token has expired at 1970-01-01T00:08:20.000Z.' }) t.assert.equal(verifier.cache.size, 1) - t.assert.ok(verifier.cache.get(hashToken(token))[0] instanceof TokenError) + t.assert.ok(verifier.cache.get(token)[0] instanceof TokenError) t.assert.throws(() => verifier(token), { message: 'The token has expired at 1970-01-01T00:08:20.000Z.' }) t.assert.throws(() => verifier(token), { message: 'The token has expired at 1970-01-01T00:08:20.000Z.' }) @@ -1283,7 +1278,7 @@ test('caching - should be able to consider clockTolerance on both nbf and exp fi t.assert.throws(() => verifier(token), { message: 'The token will be active at 1970-01-01T00:04:00.000Z.' }) t.assert.equal(verifier.cache.size, 1) t.assert.throws(() => verifier(token), { message: 'The token will be active at 1970-01-01T00:04:00.000Z.' }) - t.assert.ok(verifier.cache.get(hashToken(token))[0] instanceof TokenError) + t.assert.ok(verifier.cache.get(token)[0] instanceof TokenError) // Now advance before the activation time, in clockTolerance range clock.tick(140000) @@ -1293,7 +1288,7 @@ test('caching - should be able to consider clockTolerance on both nbf and exp fi t.assert.equal(verifier.cache.size, 1) t.assert.deepStrictEqual(verifier(token), { a: 1, iat: 100, nbf: 300, exp: 500 }) t.assert.equal(verifier.cache.size, 1) - t.assert.deepStrictEqual(verifier.cache.get(hashToken(token)), [{ a: 1, iat: 100, nbf: 300, exp: 500 }, 240000, 560000]) + t.assert.deepStrictEqual(verifier.cache.get(token), [{ a: 1, iat: 100, nbf: 300, exp: 500 }, 240000, 560000]) // Now advance to activation time clock.tick(150000) @@ -1303,7 +1298,7 @@ test('caching - should be able to consider clockTolerance on both nbf and exp fi t.assert.equal(verifier.cache.size, 1) t.assert.deepStrictEqual(verifier(token), { a: 1, iat: 100, nbf: 300, exp: 500 }) t.assert.equal(verifier.cache.size, 1) - t.assert.deepStrictEqual(verifier.cache.get(hashToken(token)), [{ a: 1, iat: 100, nbf: 300, exp: 500 }, 240000, 560000]) + t.assert.deepStrictEqual(verifier.cache.get(token), [{ a: 1, iat: 100, nbf: 300, exp: 500 }, 240000, 560000]) // Now advance again after the expiry time, in clockTolerance range (current time going to be 540000 ) clock.tick(150000) @@ -1311,13 +1306,13 @@ test('caching - should be able to consider clockTolerance on both nbf and exp fi t.assert.equal(verifier.cache.size, 1) t.assert.deepStrictEqual(verifier(token), { a: 1, iat: 100, nbf: 300, exp: 500 }) t.assert.equal(verifier.cache.size, 1) - t.assert.deepStrictEqual(verifier.cache.get(hashToken(token)), [{ a: 1, iat: 100, nbf: 300, exp: 500 }, 240000, 560000]) + t.assert.deepStrictEqual(verifier.cache.get(token), [{ a: 1, iat: 100, nbf: 300, exp: 500 }, 240000, 560000]) clock.tick(100000) // The token should now be expired and the cache should have been updated to reflect it t.assert.throws(() => verifier(token), { message: 'The token has expired at 1970-01-01T00:09:20.000Z.' }) t.assert.equal(verifier.cache.size, 1) - t.assert.ok(verifier.cache.get(hashToken(token))[0] instanceof TokenError) + t.assert.ok(verifier.cache.get(token)[0] instanceof TokenError) t.assert.throws(() => verifier(token), { message: 'The token has expired at 1970-01-01T00:09:20.000Z.' }) t.assert.throws(() => verifier(token), { message: 'The token has expired at 1970-01-01T00:09:20.000Z.' }) @@ -1338,14 +1333,14 @@ test('caching - should ignore the nbf and exp when asked to', t => { t.assert.throws(() => verifier(token), { message: 'The token will be active at 1970-01-01T00:05:00.000Z.' }) t.assert.equal(verifier.cache.size, 1) t.assert.throws(() => verifier(token), { message: 'The token will be active at 1970-01-01T00:05:00.000Z.' }) - t.assert.ok(verifier.cache.get(hashToken(token))[0] instanceof TokenError) + t.assert.ok(verifier.cache.get(token)[0] instanceof TokenError) // For the verifier which ignores notBefore, the token is already active t.assert.deepStrictEqual(verifierNoNbf(token), { a: 1, iat: 100, nbf: 300, exp: 500 }) t.assert.equal(verifierNoNbf.cache.size, 1) t.assert.deepStrictEqual(verifierNoNbf(token), { a: 1, iat: 100, nbf: 300, exp: 500 }) t.assert.equal(verifierNoNbf.cache.size, 1) - t.assert.deepStrictEqual(verifierNoNbf.cache.get(hashToken(token)), [{ a: 1, iat: 100, nbf: 300, exp: 500 }, 0, 500000]) + t.assert.deepStrictEqual(verifierNoNbf.cache.get(token), [{ a: 1, iat: 100, nbf: 300, exp: 500 }, 0, 500000]) // Now advance to activation time clock.tick(200000) @@ -1355,7 +1350,7 @@ test('caching - should ignore the nbf and exp when asked to', t => { t.assert.equal(verifier.cache.size, 1) t.assert.deepStrictEqual(verifier(token), { a: 1, iat: 100, nbf: 300, exp: 500 }) t.assert.equal(verifier.cache.size, 1) - t.assert.deepStrictEqual(verifier.cache.get(hashToken(token)), [{ a: 1, iat: 100, nbf: 300, exp: 500 }, 300000, 500000]) + t.assert.deepStrictEqual(verifier.cache.get(token), [{ a: 1, iat: 100, nbf: 300, exp: 500 }, 300000, 500000]) // Now advance again after the expiry time clock.tick(210000) @@ -1363,7 +1358,7 @@ test('caching - should ignore the nbf and exp when asked to', t => { // The token should now be expired and the cache should have been updated to reflect it t.assert.throws(() => verifier(token), { message: 'The token has expired at 1970-01-01T00:08:20.000Z.' }) t.assert.equal(verifier.cache.size, 1) - t.assert.ok(verifier.cache.get(hashToken(token))[0] instanceof TokenError) + t.assert.ok(verifier.cache.get(token)[0] instanceof TokenError) t.assert.throws(() => verifier(token), { message: 'The token has expired at 1970-01-01T00:08:20.000Z.' }) t.assert.throws(() => verifier(token), { message: 'The token has expired at 1970-01-01T00:08:20.000Z.' }) @@ -1372,7 +1367,7 @@ test('caching - should ignore the nbf and exp when asked to', t => { t.assert.equal(verifierNoExp.cache.size, 1) t.assert.deepStrictEqual(verifierNoExp(token), { a: 1, iat: 100, nbf: 300, exp: 500 }) t.assert.equal(verifierNoExp.cache.size, 1) - t.assert.deepStrictEqual(verifierNoExp.cache.get(hashToken(token)), [{ a: 1, iat: 100, nbf: 300, exp: 500 }, 300000, 1110000]) + t.assert.deepStrictEqual(verifierNoExp.cache.get(token), [{ a: 1, iat: 100, nbf: 300, exp: 500 }, 300000, 1110000]) clock.uninstall() }) @@ -1401,7 +1396,7 @@ test('default errorCacheTTL should not cache errors', async t => { t.assert.equal(verifier.cache.size, 0) await t.assert.rejects(async () => verifier(token)) t.assert.equal(verifier.cache.size, 1) - t.assert.deepStrictEqual(verifier.cache.get(hashToken(token))[2], -1) + t.assert.deepStrictEqual(verifier.cache.get(token)[2], -1) clock.uninstall() }) @@ -1421,7 +1416,7 @@ test('errors should have ttl equal to errorCacheTTL', async t => { t.assert.equal(verifier.cache.size, 0) await t.assert.rejects(async () => verifier(token)) t.assert.equal(verifier.cache.size, 1) - t.assert.deepStrictEqual(verifier.cache.get(hashToken(token))[2], errorCacheTTL) + t.assert.deepStrictEqual(verifier.cache.get(token)[2], errorCacheTTL) clock.uninstall() }) @@ -1441,17 +1436,17 @@ test('errors should have ttl equal to errorCacheTTL', async t => { t.assert.equal(verifier.cache.size, 0) await t.assert.rejects(async () => verifier(token)) t.assert.equal(verifier.cache.size, 1) - t.assert.deepStrictEqual(verifier.cache.get(hashToken(token))[2], errorCacheTTL) + t.assert.deepStrictEqual(verifier.cache.get(token)[2], errorCacheTTL) clock.tick(1000) // cache hit and ttl not changed await t.assert.rejects(async () => verifier(token)) - t.assert.deepStrictEqual(verifier.cache.get(hashToken(token))[2], errorCacheTTL) + t.assert.deepStrictEqual(verifier.cache.get(token)[2], errorCacheTTL) clock.tick(errorCacheTTL) // cache expired, request performed, new ttl await t.assert.rejects(async () => verifier(token)) - t.assert.deepStrictEqual(verifier.cache.get(hashToken(token))[2], errorCacheTTL + 1000 + errorCacheTTL) + t.assert.deepStrictEqual(verifier.cache.get(token)[2], errorCacheTTL + 1000 + errorCacheTTL) clock.uninstall() }) @@ -1480,7 +1475,7 @@ test('errors should have ttl equal to errorCacheTTL as function', async t => { t.assert.equal(verifier.cache.size, 0) await t.assert.rejects(async () => verifier(token)) t.assert.equal(verifier.cache.size, 1) - t.assert.deepStrictEqual(verifier.cache.get(hashToken(token))[2], fetchKeyErrorTTL) + t.assert.deepStrictEqual(verifier.cache.get(token)[2], fetchKeyErrorTTL) clock.uninstall() }) @@ -1525,11 +1520,11 @@ test('default errorCacheTTL should not cache errors when sub millisecond executi t.assert.equal(verifier.cache.size, 1) // change cache to check if hits - verifier.cache.set(hashToken(token), [checkToken, 0, -1]) + verifier.cache.set(token, [checkToken, 0, -1]) await t.assert.rejects(async () => verifier(token)) - t.assert.notDeepStrictEqual(verifier.cache.get(hashToken(token))[0], checkToken) + t.assert.notDeepStrictEqual(verifier.cache.get(token)[0], checkToken) clock.uninstall() })