Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

byu-jwt

Package Overview
Dependencies
Maintainers
12
Versions
51
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

byu-jwt - npm Package Compare versions

Comparing version 1.0.11 to 2.0.0

20

lib/AuthenticationError.js

@@ -17,14 +17,14 @@ /**

**/
'use strict';
'use strict'
const AuthenticationError = function (message, error) {
Error.call(this, message);
Error.captureStackTrace(this, this.constructor);
this.name = 'AuthenticationError';
this.message = message;
if (error) this.inner = error;
};
Error.call(this, message)
Error.captureStackTrace(this, this.constructor)
this.name = 'AuthenticationError'
this.message = message
if (error) this.inner = error
}
AuthenticationError.prototype = Object.create(Error.prototype);
AuthenticationError.prototype.constructor = AuthenticationError;
AuthenticationError.prototype = Object.create(Error.prototype)
AuthenticationError.prototype.constructor = AuthenticationError
module.exports = AuthenticationError;
module.exports = AuthenticationError

@@ -18,8 +18,7 @@ /**

'use strict'
const debug = require('debug')('byu-jwt-cache')
const debug = require('debug')('byu-jwt-cache')
module.exports = Cache
function Cache() {
function Cache () {
const cache = {}

@@ -29,13 +28,13 @@ const data = {

timeoutId: null,
ttl: 10, // 10 minute default
ttl: 10, // 10 minute default
value: null
}
process.on('exit', () => shutdown('exit', data)) // app is closing
process.on('SIGINT', () => shutdown('SIGINT', data)) // catches ctrl+c event
process.on('SIGBREAK', () => shutdown('SIGBREAK', data)) // catches Windows ctrl+c event
process.on('SIGUSR1', () => shutdown('SIGUSR1', data)) // catches "kill pid"
process.on('SIGUSR2', () => shutdown('SIGUSR2', data)) // catches "kill pid"
process.on('exit', () => shutdown('exit', data)) // app is closing
process.on('SIGINT', () => shutdown('SIGINT', data)) // catches ctrl+c event
process.on('SIGBREAK', () => shutdown('SIGBREAK', data)) // catches Windows ctrl+c event
process.on('SIGUSR1', () => shutdown('SIGUSR1', data)) // catches "kill pid"
process.on('SIGUSR2', () => shutdown('SIGUSR2', data)) // catches "kill pid"
cache.clearCache = function() {
cache.clearCache = function () {
clearCache(data)

@@ -45,4 +44,4 @@ clearTimeout(data.timeoutId)

cache.getCache = function() {
const value = data.value;
cache.getCache = function () {
const value = data.value
debug('cache retrieved')

@@ -52,3 +51,3 @@ return value

cache.setCache = function(value) {
cache.setCache = function (value) {
if (data.ttl > 0) {

@@ -61,7 +60,7 @@ data.value = value

cache.getTTL = function() {
cache.getTTL = function () {
return data.ttl
}
cache.setTTL = function(ttl) {
cache.setTTL = function (ttl) {
data.ttl = ttl > 0 ? ttl : 0

@@ -74,3 +73,3 @@ if (Date.now() + ttlInMilliseconds(data) < data.endTime) refreshCache(data)

function clearCache(data) {
function clearCache (data) {
debug('cache cleared')

@@ -80,3 +79,3 @@ data.value = null

function refreshCache(data) {
function refreshCache (data) {
debug('cache updated')

@@ -89,8 +88,8 @@ const ttl = ttlInMilliseconds(data)

function ttlInMilliseconds(data) {
function ttlInMilliseconds (data) {
return data.ttl * 60000
}
function shutdown(mode, data) {
function shutdown (mode, data) {
clearTimeout(data.timeoutId)
}
}

@@ -18,9 +18,12 @@ /**

'use strict'
const AuthenticationError = require('./AuthenticationError')
const Cache = require('./cache')
const debug = require('debug')('byu-jwt')
const jsonWebToken = require('jsonwebtoken')
const pem = require('pem')
const request = require('./request')
const AuthenticationError = require('./AuthenticationError')
const Cache = require('./cache')
const debug = require('debug')('byu-jwt')
const jsonWebToken = require('jsonwebtoken')
const request = require('./request')
const { promisify } = require('util')
const pemGetPublicKey = promisify(require('pem').getPublicKey)
const jsonWebTokenVerify = promisify(jsonWebToken.verify)
const BYU_JWT_CURRENT = { name: '', key: 'current', header: 'x-jwt-assertion' }

@@ -32,3 +35,3 @@ const BYU_JWT_ORIGINAL = { name: 'Original', key: 'original', header: 'x-jwt-assertion-original' }

function ByuJWT(options) {
function ByuJWT (options) {
const byuJwt = {}

@@ -38,5 +41,5 @@

if (!options) options = {}
if (!options.hasOwnProperty('basePath')) options.basePath = ''
if (!options.hasOwnProperty('cacheTTL')) options.cacheTTL = 10
if (!options.hasOwnProperty('development')) options.development = false
if (!Object.hasOwnProperty.call(options, 'basePath')) options.basePath = ''
if (!Object.hasOwnProperty.call(options, 'cacheTTL')) options.cacheTTL = 10
if (!Object.hasOwnProperty.call(options, 'development')) options.development = false

@@ -53,56 +56,66 @@ // validate options

// set cache TTL
byuJwt.cache = Cache()
byuJwt.cache.setTTL(options.cacheTTL)
byuJwt.cache = { openId: Cache(), byuCert: Cache() }
byuJwt.cache.openId.setTTL(options.cacheTTL)
byuJwt.cache.byuCert.setTTL(options.cacheTTL)
byuJwt.authenticate = headers => {
return init(byuJwt.cache)
.then(openIdConfig => authenticate(byuJwt.options, openIdConfig, headers))
byuJwt.authenticate = async (headers) => {
return authenticate(byuJwt.options, byuJwt.cache, headers)
}
byuJwt.authenticateUAPIMiddleware = function(req, res, next) {
byuJwt.authenticateUAPIMiddleware = async function (req, res, next) {
debug('running authenticateUAPIMiddleware')
byuJwt.authenticate(req.headers)
.then(verifiedJWTs => {
req.verifiedJWTs = verifiedJWTs
debug('completed authenticateUAPIMiddleware')
next()
})
.catch(err => {
console.error(err.stack)
const response = err instanceof AuthenticationError
? { code: 401, message: err.message }
: { code: 500, message: 'Error determining authentication' }
debug('failed authenticateUAPIMiddleware: ' + err.stack)
res.status(response.code).send({ metadata: { validation_response: response } })
})
try {
req.verifiedJWTs = await byuJwt.authenticate(req.headers)
debug('completed authenticateUAPIMiddleware')
next()
} catch (err) {
console.error(err.stack)
const response = err instanceof AuthenticationError
? { code: 401, message: err.message }
: { code: 500, message: 'Error determining authentication' }
debug('failed authenticateUAPIMiddleware: ' + err.stack)
res.status(response.code).send({ metadata: { validation_response: response } })
}
}
byuJwt.decodeJWT = function(jwt) {
return init(byuJwt.cache)
.then(openIdConfig => decodeJWT(byuJwt.options, openIdConfig, jwt))
byuJwt.decodeJWT = async function (jwt) {
return decodeJWT(byuJwt.options, byuJwt.cache, jwt)
}
byuJwt.getOpenIdConfiguration = function() {
byuJwt.getOpenIdConfiguration = function () {
return getOpenIdConfiguration(byuJwt.cache)
}
byuJwt.getPublicKey = function() {
return init(byuJwt.cache)
.then(getPublicKey)
byuJwt.getPublicKey = async function () {
return initPublicKey(byuJwt.cache)
}
byuJwt.verifyJWT = function(jwt) {
return init(byuJwt.cache)
.then(openIdConfig => verifyJWT(byuJwt.options, openIdConfig, jwt))
.then(() => true)
.catch(() => false)
byuJwt.verifyJWT = async function (jwt) {
try {
await verifyJWT(byuJwt.options, byuJwt.cache, jwt)
return true
} catch (e) {
return false
}
}
Object.defineProperties(byuJwt, {
cacheTTL: {
get: function() { return byuJwt.cache.getTTL() },
set: function(ttl) { byuJwt.cache.setTTL(ttl) }
get: () => ({
openId: byuJwt.cache.openId.getTTL(),
byuCert: byuJwt.cache.byuCert.getTTL()
}),
set: (ttl) => ({
openId: byuJwt.cache.openId.setTTL(ttl),
byuCert: byuJwt.cache.byuCert.setTTL(ttl)
})
},
openIdTTL: {
get: () => byuJwt.cache.openId.getTTL(),
set: (ttl) => byuJwt.cache.openId.setTTL(ttl)
},
byuCertTTL: {
get: () => byuJwt.cache.byuCert.getTTL(),
set: (ttl) => byuJwt.cache.byuCert.setTTL(ttl)
}
})

@@ -113,6 +126,4 @@

Object.defineProperties(ByuJWT, {
'BYU_JWT_HEADER_CURRENT': {
BYU_JWT_HEADER_CURRENT: {
value: BYU_JWT_CURRENT.header,

@@ -122,3 +133,3 @@ writable: false

'BYU_JWT_HEADER_ORIGINAL': {
BYU_JWT_HEADER_ORIGINAL: {
value: BYU_JWT_ORIGINAL.header,

@@ -128,3 +139,3 @@ writable: false

'AuthenticationError': {
AuthenticationError: {
value: AuthenticationError,

@@ -134,3 +145,3 @@ writable: false

'JsonWebTokenError': {
JsonWebTokenError: {
value: jsonWebToken.JsonWebTokenError,

@@ -140,3 +151,3 @@ writable: false

'NotBeforeError': {
NotBeforeError: {
value: jsonWebToken.NotBeforeError,

@@ -146,3 +157,3 @@ writable: false

'TokenExpiredError': {
TokenExpiredError: {
value: jsonWebToken.TokenExpiredError,

@@ -152,3 +163,3 @@ writable: false

'WELL_KNOWN_URL': {
WELL_KNOWN_URL: {
value: WELL_KNOWN_URL,

@@ -159,52 +170,37 @@ writable: false

function authenticate(options, openIdConfig, headers) {
const promises = []
async function authenticate (options, cache, headers) {
const verifiedJWTs = {}
// scan headers for provided JWT info
;[BYU_JWT_ORIGINAL, BYU_JWT_CURRENT]
.forEach(data => {
if (headers[data.header]) {
debug('verifying JWT in header ' + data.header)
const promise = decodeJWT(options, openIdConfig, headers[data.header])
.then(decodedJWT => {
debug('verify JWT complete for header ' + data.header)
verifiedJWTs[data.key] = decodedJWT
})
.catch(err => {
debug('verify JWT failed for header ' + data.header + ': ' + err.stack)
const name = (data.name ? data.name + ' ' : '')
const prefix = err instanceof jsonWebToken.TokenExpiredError ? 'Expired ' : 'Invalid '
throw new AuthenticationError(prefix + name + 'JWT', err)
})
promises.push(promise)
} else {
promises.push(null)
await Promise.all([BYU_JWT_ORIGINAL, BYU_JWT_CURRENT].map(async ({ header, name, key }) => {
if (headers[header]) {
debug('verifying JWT in header ' + header)
try {
const decodedJWT = await decodeJWT(options, cache, headers[header])
debug('verify JWT complete for header ' + header)
verifiedJWTs[key] = decodedJWT
} catch (err) {
debug('verify JWT failed for header ' + header + ': ' + err.stack)
const prefix = err instanceof jsonWebToken.TokenExpiredError ? 'Expired ' : 'Invalid '
throw new AuthenticationError(prefix + (name ? name + ' ' : '') + 'JWT', err)
}
})
}
}))
return Promise.all(promises)
.then(() => {
if (!verifiedJWTs.current) {
debug('verify JWT missing expected JWT')
throw new AuthenticationError('Missing expected JWT')
}
if (!verifiedJWTs.current) {
debug('verify JWT missing expected JWT')
throw new AuthenticationError('Missing expected JWT')
}
// extra validation step for production
if (!options.development && options.basePath) {
const context = verifiedJWTs.current.raw['http://wso2.org/claims/apicontext']
if (!context.startsWith(options.basePath)) throw new AuthenticationError('Invalid API context in JWT')
}
// extra validation step for production
if (!options.development && options.basePath) {
const context = verifiedJWTs.current.raw['http://wso2.org/claims/apicontext']
if (!context.startsWith(options.basePath)) throw new AuthenticationError('Invalid API context in JWT')
}
verifiedJWTs.originalJWT = headers[BYU_JWT_ORIGINAL.header] || headers[BYU_JWT_CURRENT.header]
verifiedJWTs.claims = (verifiedJWTs.original && verifiedJWTs.original.resourceOwner) ||
(verifiedJWTs.current && verifiedJWTs.current.resourceOwner) ||
(verifiedJWTs.original && verifiedJWTs.original.client) ||
verifiedJWTs.current.client
verifiedJWTs.originalJWT = headers[BYU_JWT_ORIGINAL.header] || headers[BYU_JWT_CURRENT.header]
verifiedJWTs.claims = (verifiedJWTs.original && verifiedJWTs.original.resourceOwner) ||
(verifiedJWTs.current && verifiedJWTs.current.resourceOwner) ||
(verifiedJWTs.original && verifiedJWTs.original.client) ||
verifiedJWTs.current.client
return verifiedJWTs
})
return verifiedJWTs
}

@@ -215,66 +211,59 @@

* @param {object} options
* @param {object} openIdConfig
* @param {object} cache
* @param {string} jwt
* @returns {Promise.<Object>}
*/
function decodeJWT(options, openIdConfig, jwt) {
return verifyJWT(options, openIdConfig, jwt)
.then(verifiedJWT => {
const hasResourceOwner = typeof verifiedJWT['http://byu.edu/claims/resourceowner_byu_id'] !== "undefined"
const result = {}
result.client = {
byuId: verifiedJWT['http://byu.edu/claims/client_byu_id'],
claimSource: verifiedJWT['http://byu.edu/claims/client_claim_source'],
netId: verifiedJWT['http://byu.edu/claims/client_net_id'],
personId: verifiedJWT['http://byu.edu/claims/client_person_id'],
preferredFirstName: verifiedJWT['http://byu.edu/claims/client_preferred_first_name'],
prefix: verifiedJWT['http://byu.edu/claims/client_name_prefix'],
restOfName: verifiedJWT['http://byu.edu/claims/client_rest_of_name'],
sortName: verifiedJWT['http://byu.edu/claims/client_sort_name'],
subscriberNetId: verifiedJWT['http://byu.edu/claims/client_subscriber_net_id'],
suffix: verifiedJWT['http://byu.edu/claims/client_name_prefix'],
surname: verifiedJWT['http://byu.edu/claims/client_surname'],
surnamePosition: verifiedJWT['http://byu.edu/claims/client_surname_position']
async function decodeJWT (options, cache, jwt) {
const verifiedJWT = await verifyJWT(options, cache, jwt)
const hasResourceOwner = typeof verifiedJWT['http://byu.edu/claims/resourceowner_byu_id'] !== 'undefined'
const result = {
client: {
byuId: verifiedJWT['http://byu.edu/claims/client_byu_id'],
claimSource: verifiedJWT['http://byu.edu/claims/client_claim_source'],
netId: verifiedJWT['http://byu.edu/claims/client_net_id'],
personId: verifiedJWT['http://byu.edu/claims/client_person_id'],
preferredFirstName: verifiedJWT['http://byu.edu/claims/client_preferred_first_name'],
prefix: verifiedJWT['http://byu.edu/claims/client_name_prefix'],
restOfName: verifiedJWT['http://byu.edu/claims/client_rest_of_name'],
sortName: verifiedJWT['http://byu.edu/claims/client_sort_name'],
subscriberNetId: verifiedJWT['http://byu.edu/claims/client_subscriber_net_id'],
suffix: verifiedJWT['http://byu.edu/claims/client_name_prefix'],
surname: verifiedJWT['http://byu.edu/claims/client_surname'],
surnamePosition: verifiedJWT['http://byu.edu/claims/client_surname_position']
},
...(hasResourceOwner && {
resourceOwner: {
byuId: verifiedJWT['http://byu.edu/claims/resourceowner_byu_id'],
netId: verifiedJWT['http://byu.edu/claims/resourceowner_net_id'],
personId: verifiedJWT['http://byu.edu/claims/resourceowner_person_id'],
preferredFirstName: verifiedJWT['http://byu.edu/claims/resourceowner_preferred_first_name'],
prefix: verifiedJWT['http://byu.edu/claims/resourceowner_prefix'],
restOfName: verifiedJWT['http://byu.edu/claims/resourceowner_rest_of_name'],
sortName: verifiedJWT['http://byu.edu/claims/resourceowner_sort_name'],
suffix: verifiedJWT['http://byu.edu/claims/resourceowner_suffix'],
surname: verifiedJWT['http://byu.edu/claims/resourceowner_surname'],
surnamePosition: verifiedJWT['http://byu.edu/claims/resourceowner_surname_position']
}
if (hasResourceOwner) {
result.resourceOwner = {
byuId: verifiedJWT['http://byu.edu/claims/resourceowner_byu_id'],
netId: verifiedJWT['http://byu.edu/claims/resourceowner_net_id'],
personId: verifiedJWT['http://byu.edu/claims/resourceowner_person_id'],
preferredFirstName: verifiedJWT['http://byu.edu/claims/resourceowner_preferred_first_name'],
prefix: verifiedJWT['http://byu.edu/claims/resourceowner_prefix'],
restOfName: verifiedJWT['http://byu.edu/claims/resourceowner_rest_of_name'],
sortName: verifiedJWT['http://byu.edu/claims/resourceowner_sort_name'],
suffix: verifiedJWT['http://byu.edu/claims/resourceowner_suffix'],
surname: verifiedJWT['http://byu.edu/claims/resourceowner_surname'],
surnamePosition: verifiedJWT['http://byu.edu/claims/resourceowner_surname_position']
}
}
result.claims = hasResourceOwner ? result.resourceOwner : result.client
result.raw = verifiedJWT
result.wso2 = {
apiContext: verifiedJWT["http://wso2.org/claims/apicontext"],
application: {
id: verifiedJWT["http://wso2.org/claims/applicationid"],
name: verifiedJWT["http://wso2.org/claims/applicationname"],
tier: verifiedJWT["http://wso2.org/claims/applicationtier"]
},
clientId: verifiedJWT["http://wso2.org/claims/client_id"],
endUser: verifiedJWT["http://wso2.org/claims/enduser"],
endUserTenantId: verifiedJWT["http://wso2.org/claims/enduserTenantId"],
keyType: verifiedJWT["http://wso2.org/claims/keytype"],
subscriber: verifiedJWT["http://wso2.org/claims/subscriber"],
tier: verifiedJWT["http://wso2.org/claims/tier"],
userType: verifiedJWT["http://wso2.org/claims/usertype"],
version: verifiedJWT["http://wso2.org/claims/version"]
}
debug('decoded JWT')
return result
})
}),
raw: verifiedJWT,
wso2: {
apiContext: verifiedJWT['http://wso2.org/claims/apicontext'],
application: {
id: verifiedJWT['http://wso2.org/claims/applicationid'],
name: verifiedJWT['http://wso2.org/claims/applicationname'],
tier: verifiedJWT['http://wso2.org/claims/applicationtier']
},
clientId: verifiedJWT['http://wso2.org/claims/client_id'],
endUser: verifiedJWT['http://wso2.org/claims/enduser'],
endUserTenantId: verifiedJWT['http://wso2.org/claims/enduserTenantId'],
keyType: verifiedJWT['http://wso2.org/claims/keytype'],
subscriber: verifiedJWT['http://wso2.org/claims/subscriber'],
tier: verifiedJWT['http://wso2.org/claims/tier'],
userType: verifiedJWT['http://wso2.org/claims/usertype'],
version: verifiedJWT['http://wso2.org/claims/version']
}
}
result.claims = hasResourceOwner ? result.resourceOwner : result.client
debug('decoded JWT')
return result
}

@@ -286,11 +275,16 @@

*/
function getOpenIdConfiguration(cache) {
async function getOpenIdConfiguration (cache) {
debug('get OpenID configuration')
const promise = request(WELL_KNOWN_URL)
.catch(err => {
cache.clearCache()
throw err
})
cache.setCache(promise)
return promise
try {
const config = await request(WELL_KNOWN_URL)
debug('OpenID configuration acquired')
const maxAge = getMaxAge(config.headers)
const ttl = maxAgeInMinutes(maxAge)
cache.openId.setTTL(ttl)
cache.openId.setCache(config.body)
return config.body
} catch (err) {
cache.openId.clearCache()
throw err
}
}

@@ -300,31 +294,58 @@

* Get the public key for the OpenID configuration
* @param {object} openIdConfig
* @param {object} cache
* @returns {string}
*/
function getPublicKey(openIdConfig) {
async function getPublicKey (cache) {
debug('getting public key')
return request(openIdConfig["jwks_uri"])
.then(result => {
const keys = result.keys
const cert =
"-----BEGIN CERTIFICATE-----\n" +
keys[0].x5c[0].replace(/(.{64})/g, "$1\n") +
"\n-----END CERTIFICATE-----"
const openIdConfig = await initOpenId(cache)
try {
const result = await request(openIdConfig.jwks_uri)
const cert =
'-----BEGIN CERTIFICATE-----\n' +
result.body.keys[0].x5c[0].replace(/(.{64})/g, '$1\n') +
'\n-----END CERTIFICATE-----'
//extract public key
return new Promise((resolve, reject) => {
pem.getPublicKey(cert, (err, data) => {
if (err) {
debug('failed to get public key')
reject(err)
} else {
debug('public key acquired')
resolve(data.publicKey)
}
})
})
})
// extract public key
const { publicKey } = await pemGetPublicKey(cert)
debug('public key acquired')
const maxAge = getMaxAge(result.headers)
const ttl = maxAgeInMinutes(maxAge)
cache.byuCert.setTTL(ttl)
cache.byuCert.setCache(publicKey)
return publicKey
} catch (err) {
debug('failed to get public key')
cache.byuCert.clearCache()
throw err
}
}
/**
* Get the max-age cache control from headers
* @params {object} headers
* @returns {number}
*/
function getMaxAge (headers) {
debug('getting max age from cache control header')
const cacheControl = headers['cache-control']
let [, maxAge] = cacheControl.match(/max-age=(\d+)/) // Get digits
maxAge = parseInt(maxAge, 10)
if (!maxAge) {
debug('defaulting max age to 3600')
return 3600
}
debug(`max age is ${maxAge}`)
return maxAge
}
/**
* Convert seconds to mintues
* @params {number} seconds
* @returns {number}
*/
function maxAgeInMinutes (seconds) {
return Math.floor(seconds / 60)
}
/**
* Get cached OpenID configuration or new OpenID configuration if the cached is expired.

@@ -334,15 +355,18 @@ * @param {object} cache

*/
function init(cache) {
return cache.getCache() || getOpenIdConfiguration(cache)
function initOpenId (cache) {
return cache.openId.getCache() || getOpenIdConfiguration(cache)
}
async function initPublicKey (cache) {
return cache.byuCert.getCache() || getPublicKey(cache)
}
/**
* Verify the JWT against the OpenID configuration.
* @param {object} options
* @param {object} openIdConfig
* @param {object} cache
* @param {string} jwt
* @returns {Promise<Object>}
*/
function verifyJWT(options, openIdConfig, jwt) {
async function verifyJWT (options, cache, jwt) {
// we can skip verification

@@ -352,25 +376,19 @@ if (options.development) {

debug('JWT verification skipped in development mode')
return Promise.resolve(jsonWebToken.decode(jwt))
return jsonWebToken.decode(jwt)
}
const algorithms = openIdConfig["id_token_signing_alg_values_supported"]
return getPublicKey(openIdConfig)
.then(publicKey => {
return new Promise(function(resolve, reject) {
debug('verifying JWT')
return jsonWebToken.verify(jwt, publicKey, {algorithms: algorithms}, (err, decoded) => {
if (err) {
if (err.name === 'TokenExpiredError') {
debug('token expired at ' + err.expiredAt + ' for JWT ' + jwt)
} else {
debug('failed verifying JWT: ' + err.message + ' for JWT ' + jwt)
}
reject(err)
} else {
debug('verified JWT')
resolve(decoded)
}
})
})
})
}
const openIdConfig = await initOpenId(cache)
const algorithms = openIdConfig.id_token_signing_alg_values_supported
const publicKey = await getPublicKey(cache)
debug('verifying JWT')
try {
const verifiedJWT = await jsonWebTokenVerify(jwt, publicKey, { algorithms })
debug('verified JWT')
return verifiedJWT
} catch (err) {
if (err.name === 'TokenExpiredError') debug('token expired at ' + err.expiredAt + ' for JWT ' + jwt)
else debug('failed verifying JWT: ' + err.message + ' for JWT ' + jwt)
throw err
}
}

@@ -18,5 +18,5 @@ /**

'use strict'
const debug = require('debug')('byu-jwt-request')
const http = require('http')
const https = require('https')
const debug = require('debug')('byu-jwt-request')
const http = require('http')
const https = require('https')

@@ -26,6 +26,6 @@ /**

* @param {string} url
* @returns {Promise<Object>}
* @returns {Promise<{ body: Object, headers: Object }>}
*/
module.exports = function request(url) {
debug('making request to ' + url);
module.exports = function request (url) {
debug('making request to ' + url)
return new Promise((resolve, reject) => {

@@ -40,8 +40,11 @@ const mod = /^https/.test(url) ? https : http

res.on('end', () => {
debug('completed request to ' + url);
debug('completed request to ' + url)
let body
const headers = res.headers
try {
resolve(JSON.parse(data))
body = JSON.parse(data)
} catch (err) {
reject(Error('Invalid response body:' + data))
}
resolve({ body, headers })
})

@@ -51,6 +54,6 @@ })

req.on('error', err => {
debug('failed request to ' + url);
debug('failed request to ' + url)
reject(err)
})
})
}
}
{
"name": "byu-jwt",
"version": "1.0.11",
"version": "2.0.0",
"description": "The byu-jwt module provides helpful functions to retrieve a specified BYU .well-known URL and verify BYU signed JWTs.",

@@ -16,4 +16,8 @@ "main": "index.js",

"scripts": {
"test": "mocha test"
"test": "mocha test",
"lint": "./node_modules/.bin/standard --fix"
},
"engines": {
"node": ">=8"
},
"homepage": "https://github.com/byu-oit/byu-jwt-nodejs#readme",

@@ -23,10 +27,11 @@ "dependencies": {

"jsonwebtoken": "^8.5.1",
"pem": "^1.14.2"
"pem": "^1.14.3"
},
"devDependencies": {
"aws-sdk": "^2.472.0",
"aws-sdk": "^2.578.0",
"chai": "^4.2.0",
"mocha": "^6.1.4",
"request": "^2.88.0"
"mocha": "^6.2.2",
"request": "^2.88.0",
"standard": "^14.3.1"
}
}

@@ -5,4 +5,7 @@ # byu-jwt

**Requires Node 8 or above**
## Table of Contents
- [Migrate from v1 to v2](#migrate-from-v1-to-v2)
- [API](#api)

@@ -20,2 +23,5 @@ - [Constructor](#constructor)

## Migrate from v1 to v2
* Update to Node 8 or above
## API

@@ -22,0 +28,0 @@

@@ -17,8 +17,10 @@ /*

*/
const AWS = require('aws-sdk')
const expect = require('chai').expect
const ByuJWT = require('../index')
const request = require('request')
/* global describe it beforeEach before */
describe('byu-jwt', function() {
const AWS = require('aws-sdk')
const expect = require('chai').expect
const ByuJWT = require('../index')
const request = require('request')
describe('byu-jwt', function () {
let byuJWT

@@ -28,25 +30,25 @@ let jwt

before(done => {
console.log('Acquiring test credentials. Please wait...');
console.log('Acquiring test credentials. Please wait...')
byuJWT = ByuJWT({ cacheTTL: 0 })
const ssm = new AWS.SSM({ region: 'us-west-2' });
const ssm = new AWS.SSM({ region: 'us-west-2' })
const params = {
Name: 'wabs-oauth-test.dev.config',
WithDecryption: true
};
ssm.getParameter(params, function(err, param) {
}
ssm.getParameter(params, function (err, param) {
if (err) {
console.error('AWS Error: ' + err.message);
console.error('AWS Error: ' + err.message)
console.log('Make sure that you have awslogin (https://github.com/byu-oit/awslogin) ' +
'installed, run the command "awslogin" in your terminal, and select the "dev-oit-byu" ' +
'account.');
process.exit(1);
'account.')
process.exit(1)
}
let config;
let config
try {
config = JSON.parse(param.Parameter.Value);
config = JSON.parse(param.Parameter.Value)
} catch (err) {
console.error('Parameter parsing error: ' + err.message);
process.exit(1);
console.error('Parameter parsing error: ' + err.message)
process.exit(1)
}

@@ -61,3 +63,4 @@

}
request(reqConfig, function(err, res, body) {
request(reqConfig, function (err, res, body) {
if (err) throw Error('Unable to request JWT: \n' + err)
try {

@@ -69,5 +72,5 @@ const obj = typeof body === 'object' ? body : JSON.parse(body)

}
done();
done()
})
});
})
})

@@ -91,3 +94,2 @@

describe('verifyJWT', () => {
it('valid JWT', () => {

@@ -106,7 +108,5 @@ return byuJWT.verifyJWT(jwt)

})
})
describe('decodeJWT', () => {
it('valid JWT', () => {

@@ -126,7 +126,5 @@ return byuJWT.decodeJWT(jwt)

})
})
describe('authenticate', () => {
it('valid JWT', () => {

@@ -150,3 +148,2 @@ const headers = {}

})
})

@@ -167,7 +164,7 @@

promise: deferred.promise,
status: function(code) {
status: function (code) {
this.code = code
return res
},
send: function(body) {
send: function (body) {
this.body = body

@@ -184,3 +181,3 @@ deferred.resolve()

byuJWT.authenticateUAPIMiddleware(req, res, function() {
byuJWT.authenticateUAPIMiddleware(req, res, function () {
expect(req).to.have.ownProperty('verifiedJWTs')

@@ -195,4 +192,4 @@ done()

const req = { headers: headers }
byuJWT.authenticateUAPIMiddleware(req, res, function() {
done(Error('should not get here'))
byuJWT.authenticateUAPIMiddleware(req, res, function () {
throw Error('should not get here')
})

@@ -204,5 +201,3 @@ return res.promise

})
})
});
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc