Add node modules and compiled JavaScript from main (#54)
Co-authored-by: Oliver King <oking3@uncc.edu>
This commit is contained in:
committed by
GitHub
parent
4a983766a0
commit
52d71d28bd
30
node_modules/jose/lib/jwt/decode.js
generated
vendored
Normal file
30
node_modules/jose/lib/jwt/decode.js
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
const base64url = require('../help/base64url')
|
||||
const errors = require('../errors')
|
||||
|
||||
module.exports = (token, { complete = false } = {}) => {
|
||||
if (typeof token !== 'string' || !token) {
|
||||
throw new TypeError('JWT must be a string')
|
||||
}
|
||||
|
||||
const { 0: header, 1: payload, 2: signature, length } = token.split('.')
|
||||
|
||||
if (length === 5) {
|
||||
throw new TypeError('encrypted JWTs cannot be decoded')
|
||||
}
|
||||
|
||||
if (length !== 3) {
|
||||
throw new errors.JWTMalformed('JWTs must have three components')
|
||||
}
|
||||
|
||||
try {
|
||||
const result = {
|
||||
header: base64url.JSON.decode(header),
|
||||
payload: base64url.JSON.decode(payload),
|
||||
signature
|
||||
}
|
||||
|
||||
return complete ? result : result.payload
|
||||
} catch (err) {
|
||||
throw new errors.JWTMalformed('JWT is malformed')
|
||||
}
|
||||
}
|
16
node_modules/jose/lib/jwt/index.js
generated
vendored
Normal file
16
node_modules/jose/lib/jwt/index.js
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
const decode = require('./decode')
|
||||
const sign = require('./sign')
|
||||
const verify = require('./verify')
|
||||
const profiles = require('./profiles')
|
||||
|
||||
module.exports = {
|
||||
sign,
|
||||
verify,
|
||||
...profiles
|
||||
}
|
||||
|
||||
Object.defineProperty(module.exports, 'decode', {
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
value: decode
|
||||
})
|
168
node_modules/jose/lib/jwt/profiles.js
generated
vendored
Normal file
168
node_modules/jose/lib/jwt/profiles.js
generated
vendored
Normal file
@ -0,0 +1,168 @@
|
||||
const { JWTClaimInvalid } = require('../errors')
|
||||
const secs = require('../help/secs')
|
||||
const epoch = require('../help/epoch')
|
||||
const isObject = require('../help/is_object')
|
||||
|
||||
const verify = require('./verify')
|
||||
const {
|
||||
isString,
|
||||
isRequired,
|
||||
isTimestamp,
|
||||
isStringOrArrayOfStrings
|
||||
} = require('./shared_validations')
|
||||
|
||||
const isPayloadRequired = isRequired.bind(undefined, JWTClaimInvalid)
|
||||
const isPayloadString = isString.bind(undefined, JWTClaimInvalid)
|
||||
const isOptionString = isString.bind(undefined, TypeError)
|
||||
|
||||
const defineLazyExportWithWarning = (obj, property, name, definition) => {
|
||||
Object.defineProperty(obj, property, {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
value (...args) {
|
||||
process.emitWarning(
|
||||
`The ${name} API implements an IETF draft. Breaking draft implementations are included as minor versions of the jose library, therefore, the ~ semver operator should be used and close attention be payed to library changelog as well as the drafts themselves.`,
|
||||
'DraftWarning'
|
||||
)
|
||||
Object.defineProperty(obj, property, {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
value: definition
|
||||
})
|
||||
return obj[property](...args)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const validateCommonOptions = (options, profile) => {
|
||||
if (!isObject(options)) {
|
||||
throw new TypeError('options must be an object')
|
||||
}
|
||||
|
||||
if (!options.issuer) {
|
||||
throw new TypeError(`"issuer" option is required to validate ${profile}`)
|
||||
}
|
||||
|
||||
if (!options.audience) {
|
||||
throw new TypeError(`"audience" option is required to validate ${profile}`)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
IdToken: {
|
||||
verify: (token, key, options = {}) => {
|
||||
validateCommonOptions(options, 'an ID Token')
|
||||
|
||||
if ('maxAuthAge' in options) {
|
||||
isOptionString(options.maxAuthAge, 'options.maxAuthAge')
|
||||
}
|
||||
if ('nonce' in options) {
|
||||
isOptionString(options.nonce, 'options.nonce')
|
||||
}
|
||||
|
||||
const unix = epoch(options.now || new Date())
|
||||
const result = verify(token, key, { ...options })
|
||||
const payload = options.complete ? result.payload : result
|
||||
|
||||
if (Array.isArray(payload.aud) && payload.aud.length > 1) {
|
||||
isPayloadRequired(payload.azp, '"azp" claim', 'azp')
|
||||
}
|
||||
isPayloadRequired(payload.iat, '"iat" claim', 'iat')
|
||||
isPayloadRequired(payload.sub, '"sub" claim', 'sub')
|
||||
isPayloadRequired(payload.exp, '"exp" claim', 'exp')
|
||||
isTimestamp(payload.auth_time, 'auth_time', !!options.maxAuthAge)
|
||||
isPayloadString(payload.nonce, '"nonce" claim', 'nonce', !!options.nonce)
|
||||
isPayloadString(payload.acr, '"acr" claim', 'acr')
|
||||
isStringOrArrayOfStrings(payload.amr, 'amr')
|
||||
|
||||
if (options.nonce && payload.nonce !== options.nonce) {
|
||||
throw new JWTClaimInvalid('unexpected "nonce" claim value', 'nonce', 'check_failed')
|
||||
}
|
||||
|
||||
const tolerance = options.clockTolerance ? secs(options.clockTolerance) : 0
|
||||
|
||||
if (options.maxAuthAge) {
|
||||
const maxAuthAgeSeconds = secs(options.maxAuthAge)
|
||||
if (payload.auth_time + maxAuthAgeSeconds < unix - tolerance) {
|
||||
throw new JWTClaimInvalid('"auth_time" claim timestamp check failed (too much time has elapsed since the last End-User authentication)', 'auth_time', 'check_failed')
|
||||
}
|
||||
}
|
||||
|
||||
if (Array.isArray(payload.aud) && payload.aud.length > 1 && payload.azp !== options.audience) {
|
||||
throw new JWTClaimInvalid('unexpected "azp" claim value', 'azp', 'check_failed')
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
},
|
||||
LogoutToken: {},
|
||||
AccessToken: {}
|
||||
}
|
||||
|
||||
defineLazyExportWithWarning(module.exports.LogoutToken, 'verify', 'jose.JWT.LogoutToken.verify', (token, key, options = {}) => {
|
||||
validateCommonOptions(options, 'a Logout Token')
|
||||
|
||||
const result = verify(token, key, { ...options })
|
||||
const payload = options.complete ? result.payload : result
|
||||
|
||||
isPayloadRequired(payload.iat, '"iat" claim', 'iat')
|
||||
isPayloadRequired(payload.jti, '"jti" claim', 'jti')
|
||||
isPayloadString(payload.sid, '"sid" claim', 'sid')
|
||||
|
||||
if (!('sid' in payload) && !('sub' in payload)) {
|
||||
throw new JWTClaimInvalid('either "sid" or "sub" (or both) claims must be present')
|
||||
}
|
||||
|
||||
if ('nonce' in payload) {
|
||||
throw new JWTClaimInvalid('"nonce" claim is prohibited', 'nonce', 'prohibited')
|
||||
}
|
||||
|
||||
if (!('events' in payload)) {
|
||||
throw new JWTClaimInvalid('"events" claim is missing', 'events', 'missing')
|
||||
}
|
||||
|
||||
if (!isObject(payload.events)) {
|
||||
throw new JWTClaimInvalid('"events" claim must be an object', 'events', 'invalid')
|
||||
}
|
||||
|
||||
if (!('http://schemas.openid.net/event/backchannel-logout' in payload.events)) {
|
||||
throw new JWTClaimInvalid('"http://schemas.openid.net/event/backchannel-logout" member is missing in the "events" claim', 'events', 'invalid')
|
||||
}
|
||||
|
||||
if (!isObject(payload.events['http://schemas.openid.net/event/backchannel-logout'])) {
|
||||
throw new JWTClaimInvalid('"http://schemas.openid.net/event/backchannel-logout" member in the "events" claim must be an object', 'events', 'invalid')
|
||||
}
|
||||
|
||||
return result
|
||||
})
|
||||
|
||||
defineLazyExportWithWarning(module.exports.AccessToken, 'verify', 'jose.JWT.AccessToken.verify', (token, key, options = {}) => {
|
||||
validateCommonOptions(options, 'a JWT Access Token')
|
||||
|
||||
isOptionString(options.maxAuthAge, 'options.maxAuthAge')
|
||||
|
||||
const unix = epoch(options.now || new Date())
|
||||
const typ = 'at+JWT'
|
||||
const result = verify(token, key, { ...options, typ })
|
||||
const payload = options.complete ? result.payload : result
|
||||
|
||||
isPayloadRequired(payload.iat, '"iat" claim', 'iat')
|
||||
isPayloadRequired(payload.exp, '"exp" claim', 'exp')
|
||||
isPayloadRequired(payload.sub, '"sub" claim', 'sub')
|
||||
isPayloadRequired(payload.jti, '"jti" claim', 'jti')
|
||||
isPayloadString(payload.client_id, '"client_id" claim', 'client_id', true)
|
||||
isTimestamp(payload.auth_time, 'auth_time', !!options.maxAuthAge)
|
||||
isPayloadString(payload.acr, '"acr" claim', 'acr')
|
||||
isStringOrArrayOfStrings(payload.amr, 'amr')
|
||||
|
||||
const tolerance = options.clockTolerance ? secs(options.clockTolerance) : 0
|
||||
|
||||
if (options.maxAuthAge) {
|
||||
const maxAuthAgeSeconds = secs(options.maxAuthAge)
|
||||
if (payload.auth_time + maxAuthAgeSeconds < unix - tolerance) {
|
||||
throw new JWTClaimInvalid('"auth_time" claim timestamp check failed (too much time has elapsed since the last End-User authentication)', 'auth_time', 'check_failed')
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
})
|
45
node_modules/jose/lib/jwt/shared_validations.js
generated
vendored
Normal file
45
node_modules/jose/lib/jwt/shared_validations.js
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
const { JWTClaimInvalid } = require('../errors')
|
||||
|
||||
const isNotString = val => typeof val !== 'string' || val.length === 0
|
||||
const isNotArrayOfStrings = val => !Array.isArray(val) || val.length === 0 || val.some(isNotString)
|
||||
const isRequired = (Err, value, label, claim) => {
|
||||
if (value === undefined) {
|
||||
throw new Err(`${label} is missing`, claim, 'missing')
|
||||
}
|
||||
}
|
||||
const isString = (Err, value, label, claim, required = false) => {
|
||||
if (required) {
|
||||
isRequired(Err, value, label, claim)
|
||||
}
|
||||
|
||||
if (value !== undefined && isNotString(value)) {
|
||||
throw new Err(`${label} must be a string`, claim, 'invalid')
|
||||
}
|
||||
}
|
||||
const isTimestamp = (value, label, required = false) => {
|
||||
if (required && value === undefined) {
|
||||
throw new JWTClaimInvalid(`"${label}" claim is missing`, label, 'missing')
|
||||
}
|
||||
|
||||
if (value !== undefined && (typeof value !== 'number')) {
|
||||
throw new JWTClaimInvalid(`"${label}" claim must be a JSON numeric value`, label, 'invalid')
|
||||
}
|
||||
}
|
||||
const isStringOrArrayOfStrings = (value, label, required = false) => {
|
||||
if (required && value === undefined) {
|
||||
throw new JWTClaimInvalid(`"${label}" claim is missing`, label, 'missing')
|
||||
}
|
||||
|
||||
if (value !== undefined && (isNotString(value) && isNotArrayOfStrings(value))) {
|
||||
throw new JWTClaimInvalid(`"${label}" claim must be a string or array of strings`, label, 'invalid')
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isNotArrayOfStrings,
|
||||
isRequired,
|
||||
isNotString,
|
||||
isString,
|
||||
isTimestamp,
|
||||
isStringOrArrayOfStrings
|
||||
}
|
94
node_modules/jose/lib/jwt/sign.js
generated
vendored
Normal file
94
node_modules/jose/lib/jwt/sign.js
generated
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
const isObject = require('../help/is_object')
|
||||
const secs = require('../help/secs')
|
||||
const epoch = require('../help/epoch')
|
||||
const getKey = require('../help/get_key')
|
||||
const JWS = require('../jws')
|
||||
|
||||
const isString = require('./shared_validations').isString.bind(undefined, TypeError)
|
||||
|
||||
const validateOptions = (options) => {
|
||||
if (typeof options.iat !== 'boolean') {
|
||||
throw new TypeError('options.iat must be a boolean')
|
||||
}
|
||||
|
||||
if (typeof options.kid !== 'boolean') {
|
||||
throw new TypeError('options.kid must be a boolean')
|
||||
}
|
||||
|
||||
isString(options.subject, 'options.subject')
|
||||
isString(options.issuer, 'options.issuer')
|
||||
|
||||
if (
|
||||
options.audience !== undefined &&
|
||||
(
|
||||
(typeof options.audience !== 'string' || !options.audience) &&
|
||||
(!Array.isArray(options.audience) || options.audience.length === 0 || options.audience.some(a => !a || typeof a !== 'string'))
|
||||
)
|
||||
) {
|
||||
throw new TypeError('options.audience must be a string or an array of strings')
|
||||
}
|
||||
|
||||
if (!isObject(options.header)) {
|
||||
throw new TypeError('options.header must be an object')
|
||||
}
|
||||
|
||||
isString(options.algorithm, 'options.algorithm')
|
||||
isString(options.expiresIn, 'options.expiresIn')
|
||||
isString(options.notBefore, 'options.notBefore')
|
||||
isString(options.jti, 'options.jti')
|
||||
|
||||
if (options.now !== undefined && (!(options.now instanceof Date) || !options.now.getTime())) {
|
||||
throw new TypeError('options.now must be a valid Date object')
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = (payload, key, options = {}) => {
|
||||
if (!isObject(options)) {
|
||||
throw new TypeError('options must be an object')
|
||||
}
|
||||
|
||||
const {
|
||||
algorithm, audience, expiresIn, header = {}, iat = true,
|
||||
issuer, jti, kid = true, notBefore, subject, now
|
||||
} = options
|
||||
|
||||
validateOptions({
|
||||
algorithm, audience, expiresIn, header, iat, issuer, jti, kid, notBefore, now, subject
|
||||
})
|
||||
|
||||
if (!isObject(payload)) {
|
||||
throw new TypeError('payload must be an object')
|
||||
}
|
||||
|
||||
let unix
|
||||
if (expiresIn || notBefore || iat) {
|
||||
unix = epoch(now || new Date())
|
||||
}
|
||||
|
||||
payload = {
|
||||
...payload,
|
||||
sub: subject || payload.sub,
|
||||
aud: audience || payload.aud,
|
||||
iss: issuer || payload.iss,
|
||||
jti: jti || payload.jti,
|
||||
iat: iat ? unix : payload.iat,
|
||||
exp: expiresIn ? unix + secs(expiresIn) : payload.exp,
|
||||
nbf: notBefore ? unix + secs(notBefore) : payload.nbf
|
||||
}
|
||||
|
||||
key = getKey(key)
|
||||
|
||||
let includeKid
|
||||
|
||||
if (typeof options.kid === 'boolean') {
|
||||
includeKid = kid
|
||||
} else {
|
||||
includeKid = !key.secret
|
||||
}
|
||||
|
||||
return JWS.sign(JSON.stringify(payload), key, {
|
||||
...header,
|
||||
alg: algorithm || header.alg,
|
||||
kid: includeKid ? key.kid : header.kid
|
||||
})
|
||||
}
|
186
node_modules/jose/lib/jwt/verify.js
generated
vendored
Normal file
186
node_modules/jose/lib/jwt/verify.js
generated
vendored
Normal file
@ -0,0 +1,186 @@
|
||||
const isObject = require('../help/is_object')
|
||||
const epoch = require('../help/epoch')
|
||||
const secs = require('../help/secs')
|
||||
const getKey = require('../help/get_key')
|
||||
const { bare: verify } = require('../jws/verify')
|
||||
const { JWTClaimInvalid, JWTExpired } = require('../errors')
|
||||
|
||||
const {
|
||||
isString,
|
||||
isNotString,
|
||||
isNotArrayOfStrings,
|
||||
isTimestamp,
|
||||
isStringOrArrayOfStrings
|
||||
} = require('./shared_validations')
|
||||
const decode = require('./decode')
|
||||
|
||||
const isPayloadString = isString.bind(undefined, JWTClaimInvalid)
|
||||
const isOptionString = isString.bind(undefined, TypeError)
|
||||
|
||||
const normalizeTyp = (value) => value.toLowerCase().replace(/^application\//, '')
|
||||
|
||||
const validateOptions = ({
|
||||
algorithms, audience, clockTolerance, complete = false, crit, ignoreExp = false,
|
||||
ignoreIat = false, ignoreNbf = false, issuer, jti, maxTokenAge, now = new Date(),
|
||||
subject, typ
|
||||
}) => {
|
||||
if (typeof complete !== 'boolean') {
|
||||
throw new TypeError('options.complete must be a boolean')
|
||||
}
|
||||
|
||||
if (typeof ignoreExp !== 'boolean') {
|
||||
throw new TypeError('options.ignoreExp must be a boolean')
|
||||
}
|
||||
|
||||
if (typeof ignoreNbf !== 'boolean') {
|
||||
throw new TypeError('options.ignoreNbf must be a boolean')
|
||||
}
|
||||
|
||||
if (typeof ignoreIat !== 'boolean') {
|
||||
throw new TypeError('options.ignoreIat must be a boolean')
|
||||
}
|
||||
|
||||
isOptionString(maxTokenAge, 'options.maxTokenAge')
|
||||
isOptionString(subject, 'options.subject')
|
||||
isOptionString(jti, 'options.jti')
|
||||
isOptionString(clockTolerance, 'options.clockTolerance')
|
||||
isOptionString(typ, 'options.typ')
|
||||
|
||||
if (issuer !== undefined && (isNotString(issuer) && isNotArrayOfStrings(issuer))) {
|
||||
throw new TypeError('options.issuer must be a string or an array of strings')
|
||||
}
|
||||
|
||||
if (audience !== undefined && (isNotString(audience) && isNotArrayOfStrings(audience))) {
|
||||
throw new TypeError('options.audience must be a string or an array of strings')
|
||||
}
|
||||
|
||||
if (algorithms !== undefined && isNotArrayOfStrings(algorithms)) {
|
||||
throw new TypeError('options.algorithms must be an array of strings')
|
||||
}
|
||||
|
||||
if (!(now instanceof Date) || !now.getTime()) {
|
||||
throw new TypeError('options.now must be a valid Date object')
|
||||
}
|
||||
|
||||
if (ignoreIat && maxTokenAge !== undefined) {
|
||||
throw new TypeError('options.ignoreIat and options.maxTokenAge cannot used together')
|
||||
}
|
||||
|
||||
if (crit !== undefined && isNotArrayOfStrings(crit)) {
|
||||
throw new TypeError('options.crit must be an array of strings')
|
||||
}
|
||||
|
||||
return {
|
||||
algorithms,
|
||||
audience,
|
||||
clockTolerance,
|
||||
complete,
|
||||
crit,
|
||||
ignoreExp,
|
||||
ignoreIat,
|
||||
ignoreNbf,
|
||||
issuer,
|
||||
jti,
|
||||
maxTokenAge,
|
||||
now,
|
||||
subject,
|
||||
typ
|
||||
}
|
||||
}
|
||||
|
||||
const validateTypes = ({ header, payload }, options) => {
|
||||
isPayloadString(header.alg, '"alg" header parameter', 'alg', true)
|
||||
|
||||
isTimestamp(payload.iat, 'iat', !!options.maxTokenAge)
|
||||
isTimestamp(payload.exp, 'exp')
|
||||
isTimestamp(payload.nbf, 'nbf')
|
||||
isPayloadString(payload.jti, '"jti" claim', 'jti', !!options.jti)
|
||||
isStringOrArrayOfStrings(payload.iss, 'iss', !!options.issuer)
|
||||
isPayloadString(payload.sub, '"sub" claim', 'sub', !!options.subject)
|
||||
isStringOrArrayOfStrings(payload.aud, 'aud', !!options.audience)
|
||||
isPayloadString(header.typ, '"typ" header parameter', 'typ', !!options.typ)
|
||||
}
|
||||
|
||||
const checkAudiencePresence = (audPayload, audOption) => {
|
||||
if (typeof audPayload === 'string') {
|
||||
return audOption.includes(audPayload)
|
||||
}
|
||||
|
||||
// Each principal intended to process the JWT MUST
|
||||
// identify itself with a value in the audience claim
|
||||
audPayload = new Set(audPayload)
|
||||
return audOption.some(Set.prototype.has.bind(audPayload))
|
||||
}
|
||||
|
||||
module.exports = (token, key, options = {}) => {
|
||||
if (!isObject(options)) {
|
||||
throw new TypeError('options must be an object')
|
||||
}
|
||||
|
||||
const {
|
||||
algorithms, audience, clockTolerance, complete, crit, ignoreExp, ignoreIat, ignoreNbf, issuer,
|
||||
jti, maxTokenAge, now, subject, typ
|
||||
} = options = validateOptions(options)
|
||||
|
||||
const decoded = decode(token, { complete: true })
|
||||
key = getKey(key, true)
|
||||
|
||||
if (complete) {
|
||||
({ key } = verify(true, 'preparsed', { decoded, token }, key, { crit, algorithms, complete: true }))
|
||||
decoded.key = key
|
||||
} else {
|
||||
verify(true, 'preparsed', { decoded, token }, key, { crit, algorithms })
|
||||
}
|
||||
|
||||
const unix = epoch(now)
|
||||
validateTypes(decoded, options)
|
||||
|
||||
if (issuer && (typeof decoded.payload.iss !== 'string' || !(typeof issuer === 'string' ? [issuer] : issuer).includes(decoded.payload.iss))) {
|
||||
throw new JWTClaimInvalid('unexpected "iss" claim value', 'iss', 'check_failed')
|
||||
}
|
||||
|
||||
if (subject && decoded.payload.sub !== subject) {
|
||||
throw new JWTClaimInvalid('unexpected "sub" claim value', 'sub', 'check_failed')
|
||||
}
|
||||
|
||||
if (jti && decoded.payload.jti !== jti) {
|
||||
throw new JWTClaimInvalid('unexpected "jti" claim value', 'jti', 'check_failed')
|
||||
}
|
||||
|
||||
if (audience && !checkAudiencePresence(decoded.payload.aud, typeof audience === 'string' ? [audience] : audience)) {
|
||||
throw new JWTClaimInvalid('unexpected "aud" claim value', 'aud', 'check_failed')
|
||||
}
|
||||
|
||||
if (typ && normalizeTyp(decoded.header.typ) !== normalizeTyp(typ)) {
|
||||
throw new JWTClaimInvalid('unexpected "typ" JWT header value', 'typ', 'check_failed')
|
||||
}
|
||||
|
||||
const tolerance = clockTolerance ? secs(clockTolerance) : 0
|
||||
|
||||
if (!ignoreIat && !('exp' in decoded.payload) && 'iat' in decoded.payload && decoded.payload.iat > unix + tolerance) {
|
||||
throw new JWTClaimInvalid('"iat" claim timestamp check failed (it should be in the past)', 'iat', 'check_failed')
|
||||
}
|
||||
|
||||
if (!ignoreNbf && 'nbf' in decoded.payload && decoded.payload.nbf > unix + tolerance) {
|
||||
throw new JWTClaimInvalid('"nbf" claim timestamp check failed', 'nbf', 'check_failed')
|
||||
}
|
||||
|
||||
if (!ignoreExp && 'exp' in decoded.payload && decoded.payload.exp <= unix - tolerance) {
|
||||
throw new JWTExpired('"exp" claim timestamp check failed', 'exp', 'check_failed')
|
||||
}
|
||||
|
||||
if (maxTokenAge) {
|
||||
const age = unix - decoded.payload.iat
|
||||
const max = secs(maxTokenAge)
|
||||
|
||||
if (age - tolerance > max) {
|
||||
throw new JWTExpired('"iat" claim timestamp check failed (too far in the past)', 'iat', 'check_failed')
|
||||
}
|
||||
|
||||
if (age < 0 - tolerance) {
|
||||
throw new JWTClaimInvalid('"iat" claim timestamp check failed (it should be in the past)', 'iat', 'check_failed')
|
||||
}
|
||||
}
|
||||
|
||||
return complete ? decoded : decoded.payload
|
||||
}
|
Reference in New Issue
Block a user