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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@abramltd/jwt-oauth2-middleware

v0.1.0

Published

This project defines some middleware for the creation of OAuth Server using oauth2-node. An example is given using express as the intended server. Currently only password and refresh_token grants are supported.

Readme

JWT OAUTH Middleware

This project defines some middleware for the creation of OAuth Server using oauth2-node. An example is given using express as the intended server. Currently only password and refresh_token grants are supported.

Usage & routes

Short usage version (example with express.js server):

    var oauth = require('insert-package-name')(model, config); // creating server middleware
    ... // express needed stuff

    app.post('/oauth/token', oauth.token); // (1) and (2)

    app.get('/validate', oauth.authenticate, function (req, res) { // (3)
        res.json({ message: 'Secure data' });
    });

Any OAuth server that implements password and refresh_token grant types, needs to have three routes:

  • one for generating access tokens (1)
  • one for generating new access tokens from unexpired refresh tokens (2)
  • one for token validation/gathering sensitive information (3)

Generating access tokens

Usually, the route for acquiring an access token for a user is /token. The request needs to be HTTP/HTTPS POST and required data is sent in the request's body.

|Required data| Value| | ------------------ | ---------------- | |username| user's account username| |client_id| Id of the client (application) that is requesting the user's access token| |password| user's account password| |grant_type|password | |client_secret|client's secret used to sign token data| |scope|the scope the generated access token needs to have|

The return value example is shown below.

    {
        "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRJZCI6IjEyMzUiLCJ1c2VySWQiOiI1OGVkMDUwYTczNGQxZDBlNjVmYzc3OTQiLCJ0eXBlIjoiYWNjZXNzVG9rZW4iLCJ1c2VybmFtZSI6IkRhbmEiLCJiYW5hbmEiOiJiYW5hbmEgd2hvIiwic2NvcGUiOiJiYW5hbmEiLCJleHBpcmVEYXRlIjoxNDk4MzI4MjY3NDc2LCJpYXQiOjE0OTgzMjgyMDcsImV4cCI6MTQ5ODMyODI2N30.KygbmACDVPYGoDpUg7YiyI5oAzQ5aUv8uqG0m9BDNg4",
        "token_type": "Bearer",
        "expires_in": 59, // seconds 
        "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRJZCI6IjEyMzUiLCJ1c2VySWQiOiI1OGVkMDUwYTczNGQxZDBlNjVmYzc3OTQiLCJ0eXBlIjoicmVmcmVzaFRva2VuIiwidXNlcm5hbWUiOiJEYW5hIiwiYmFuYW5hIjoiYmFuYW5hIHdobyIsInNjb3BlIjoiYmFuYW5hIiwiZXhwaXJlRGF0ZSI6MTQ5ODMyODI2NzQ3OCwiaWF0IjoxNDk4MzI4MjA3LCJleHAiOjE0OTgzMjgyNjd9.milncP0uopHUEU56ZqG1i9IDKDkP5ANfPQPFazMZLTE",
        "scope": "banana"
    }

Generating new access tokens from unexpired refresh tokens

Usually, the route for acquiring an access token for a user is /token. The request needs to be HTTP/HTTPS POST and required data is sent in the request's body.

|Required data| Value| | ------------------ | ---------------- | |client_id| Id of the client (application) that is requesting the refresh of the user's access token| |grant_type|refresh_token | |client_secret|client's secret used to sign data, secret of the refresh token| |refresh_token|refresh token used to retrieve the new access and refresh token. Musn't be expired|

Remark: if the token isn't expired, it will be revoked and a new pair accessToken/refreshToken will be issued. In addition, the new generated tokens will have the same scope as the previously generated ones. An example is shown below.

    {
        "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRJZCI6IjEyMzUiLCJ1c2VySWQiOiI1OGVkMDUwYTczNGQxZDBlNjVmYzc3OTQiLCJ0eXBlIjoiYWNjZXNzVG9rZW4iLCJ1c2VybmFtZSI6IkRhbmEiLCJiYW5hbmEiOiJiYW5hbmEgd2hvIiwic2NvcGUiOiJiYW5hbmEiLCJleHBpcmVEYXRlIjoxNDk4MzI5MTY3OTkxLCJpYXQiOjE0OTgzMjkxMDcsImV4cCI6MTQ5ODMyOTE2N30._vbYF3f1DIcuiG_nX-8clYX6IgckIqY9n75NoLzw3tE",
        "token_type": "Bearer",
        "expires_in": 59, // seconds
        "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRJZCI6IjEyMzUiLCJ1c2VySWQiOiI1OGVkMDUwYTczNGQxZDBlNjVmYzc3OTQiLCJ0eXBlIjoicmVmcmVzaFRva2VuIiwidXNlcm5hbWUiOiJEYW5hIiwiYmFuYW5hIjoiYmFuYW5hIHdobyIsInNjb3BlIjoiYmFuYW5hIiwiZXhwaXJlRGF0ZSI6MTQ5ODMyOTE2Nzk5MywiaWF0IjoxNDk4MzI5MTA3LCJleHAiOjE0OTgzMjkxNjd9.GQU0bCFlu_qCuQgZtdTXTie6SPA08xVIv5Zv93ELFig",
        "scope": "banana"
    }

Token validation/gathering sensitive information

For validating the token or gathering sensitive information one must issue a HTTP GET request on a desired route. If scope should be validated, the request should have scope specified in the URL query. Query parameter's name is scope.

Model

In order to create the middleware object one must supply the model object and configuration. However, not all model functions need to be provided - partial functionality is provided. The following table shows which grant_types require which methods as well as show if the method is used in (1), (2) or (3).

|Model function name| Declaration| Description | Grant types | Needed for (1)? | Needed for (2)? | Needed for (3)? | | ------------------ | ---------------- | ------------------ | ---------------- | ------------------ | ---------------- |---------------- | |generateTokenData| (client, user, scope) => data directly saved into the token | Same for access token and refresh token| Both | yes | yes| no| |getClientById|(id) => Client : {id: string, refreshTokenSecret: string, accessTokenSecret: string} | Returns client object | Both | yes| yes| yes| |getUserData|(username, password) => either (User : {id: string}) or false| Returns user object | password | yes | yes | no | |revokeRefreshToken| (data) => boolean | Revokes the supplied refresh token and returns whether the operation was successful | refresh_token | no | yes | no| |saveToken| (token, user, client) => Token with user and client data attached as follows {user: {id: string}, client: {id: string}} | Saves both refresh and access tokens | Both | yes | yes| no | |validateScopeUser| (user, client, scope)=> either scope or false| Used to see whether the user/client combination should/can have certain scope | password| yes | no | no| |verifyScopeAccessToken|(data, scope) => boolean | Used to see whether the supplied access token can be used for the supplied scope| Authenticate method | no | no| yes|

revokeRefreshToken data type

 
  data = { 
      user: {id: string},
      client: {id: string},
      token: {
                    refreshToken: string, // token
                    expires: Date,
                    client: Client,
                    scope: string
      },
      scope: string
    };

verifyScopeAccessToken data type

 
  data = {
            user: { id: string},
            token: {
                accessToken: string, //bearerToken,
                expires: Date,
                client: Client,
                scope: string
            },
            scope: string
 };

Config

Config needs to define expiration in seconds for both access and refresh token. Example is provided below.


 var config = {
   accessTokenExpiry: 60,             // seconds
   refreshTokenExpiry: 60,          // seconds
 };