npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@tailored-apps/keyhole

v2.6.3

Published

gatekeeper oauth2 server companion library

Downloads

51

Readme

keyhole

gatekeeper oauth2 server companion library

Token Verification

The tokenVerification factory returns an async function that can be used to verify that a provided token is valid (i.e. it has been issued, has not revoked and is not expired). This function will throw a 401 HTTP error if the provided token is invalid, and it will do nothing for valid tokens.

API

tokenVerification ({ baseUrl, verifyEndpoint }) -> Function

  • baseUrl gatekeeper base URL
  • verifyEndpoint (optional) Endpoint used for token verification (defaults to /oauth/verify)

The function returned by this factory has the following API:

verifyToken(token, requiredScopes) -> void

  • token Access token
  • requiredScopes (optional) List of scopes the token needs to have in order to be considered valid

Example

import { tokenVerification } from 'keyhole'

export const tokenVerificationMiddleware = () => {
  const verifyToken = tokenVerification({ baseUrl: 'https://gatekeeper.tailored-apps.com' })
  
  return async (ctx, next) => {
    const [ , token ] = ctx.get('authorization').split(' ')
     
    // If you just need to make sure the token is valid
    await verifyToken(token)
    
    // or, if you also need to verify the scope:
    await verifyToken(token, [ 'required_scope', 'second_required_scope' ])
    
    // We now know the token is valid, continue
    return next()
  }
} 

Token Introspection

The tokenIntrospection factory returns an async function that can be used for introspecting arbitrary tokens. The returned function accepts only one parameter - the token which will be sent to the gatekeeper API for introspection.

As per RFC 7662, the introspection endpoint will return a 200 OK HTTP response for both valid and invalid tokens. Invalid (i.e. revoked, expired or non existing) tokens will always produce the same response: { active: false }.

API

introspection ({ baseUrl, clientId, clientSecret, requiredScopes, introspectEndpoint }) -> Function

  • baseUrl gatekeeper base URL
  • clientId Client ID used in client_credentials authentication
  • clientSecret Client secret used in client_credentials authentication
  • introspectEndpoint (optional) Endpoint used for introspection (defaults to /oauth/introspect)

Example

import { tokenIntrospection } from 'keyhole'

const token = 'asdf-foo-bar'
const introspect = tokenIntrospection({ 
  baseUrl: 'https://gatekeeper.tailored-apps.com',
  clientId: 'my-api-client-id',
  clientSecret: 'my-client-secret'
})

introspect(token)
  .then((data) => console.dir(data))
  
/*
-> 
{
  active: true,
  accessToken: 'asdf-foo-bar',
  accessTokenExpiresAt: '2017-07-18T13:01:30.016Z',
  scope: 'authenticate_user',
  clientId: 'my-api-client-id',
  user: {
    username: 'emart86',
    customProp: 'some value',
    anotherCustomProp: 'some other value'
  }
 */

Scope Verification

keyhole provides a helper function to verify that a token's scope is a superset of a list of required scopes.

API

verifyTokenScope(tokenScope, requiredScope) -> Boolean

  • tokenScope Token scope. Can either be an array or a space separated string.
  • requiredScope List of scopes the token needs to have. Can either be an array or a space separated string.

Example

import { verifyTokenScope } from 'keyhole'

verifyTokenScope('foo bar baz', 'foo') // -> true
verifyTokenScope('foo bar baz', 'foo bar') // -> true
verifyTokenScope('foo bar baz', 'bar foo') // -> true
verifyTokenScope('foo bar baz', 'foo bar qux') // -> false

Middleware

As of v2.0.0, keyhole also includes a middleware module which exports various functions that cover common usecases.

tokenVerificationMiddleware

Returns a koa middleware function that will verify a token by reading it from the Authorization header and subsequently calling the tokenVerification function (see above).

API

tokenVerificationMiddleware({ logger, baseUrl, verify, requiredScopes, verifyEndpoint }) -> Function

  • logger (optional) winston compatible logger object (defaults to console logging)
  • verify (optional) function that will be called to verify the token (defaults to tokenVerification({ baseUrl, verifyEndpoint }))

See tokenVerification API docs for baseUrl, requiredScopes and verifyEndpoint parameter explanations.

tokenIntrospectionMiddleware

Returns a koa middleware function that will introspect a token (which is read from the Authorization header) and store it's data in ctx.state. If the token fails introspection (i.e. if active === false), the token will be passed to the verify function, which will throw an appropriate error. Therefore, this middleware does not need to be used in conjunction with tokenVerificationMiddleware but should be used instead of it if token introspection data is needed at some point in the request.

This function can also verify a token's scope by comparing it against a list of requiredScopes. Since token data will already be in memory at the time of comparison, this will not perform an HTTP request for doing so, but will instead simply call the verifyTokenScope helper function locally. If in-memory verification fails, verify will be called and subsequently produce an appropriate error.

API

tokenIntrospectionMiddleware({ statePropName, logger, requiredScopes, baseUrl, clientId, clientSecret, introspect, verify, introspectEndpoint, verifyEndpoint }) -> Function

  • statePropName (optional) name of the property in ctx.state that will hold token data (defaults to tokenPayload)
  • logger (optional) winston compatible logger object (defaults to console logging)
  • requiredScopes (optional) Array of scopes the token needs to have in order to be considered valid.
  • introspect (optional) function that will be called to introspect the token (defaults to tokenIntrospection({ baseUrl, clientId, clientSecret, introspectEndpoint }))
  • verify (optional) function that will be called to verify the token (defaults to tokenVerification({ baseUrl, verifyEndpoint }))

Remaining parameters will be passed to tokenIntrospection and tokenVerification factory functions - see documentation for these functions for an explanation of the parameters they expect.

Example

import router from 'koa-router'
import { tokenIntrospectionMiddleware } from 'keyhole'

const router = new Router()

router
  .get('/something', 
    tokenIntrospectionMiddleware({ baseUrl: 'https://gatekeeper-dev.tailored-apps.com', clientId: 'someClient', clientSecret: 'secret' }),
    (ctx, next) => {
      console.dir(ctx.state.tokenPayload)
      
      return next()
    }
  )