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

@valbo/auth-middlewares

v1.0.5

Published

Express middlewares to authenticate via basic auth or JWT and to authorize based on user role

Downloads

1

Readme

@valbo/auth-middlewares

Express middlewares to authenticate via basic auth or JWT and to authorize based on user role.

npm (scoped) semantic-release Build Status Coverage Status Known Vulnerabilities

Contents

Install

npm install @valbo/auth-middlewares

Usage

This package exports express middlewares to authenticate via basic auth or JSON Web Token, and to authorize based on user roles. See the example file for a full example on how to use all these middlewares. See the options section at the end for an explanation on how to configure them.

Basic authentication

There are two basic authentication middlewares: askBasicAuth() and verifyBasicAuth().

askBasicAuth() checks for an Authorization header in the request and if it is missing it throws a 401 error and sets the WWW-Authenticate response header so that a browser asks for credentials. Always follow this middleware with verifyBasicAuth() so that when the user enters his credentials they will be verified.

verifyBasicAuth() validates an Authorization header with basic auth data. If the credentials are valid the authenticated user will be copied into response.locals.user and if the credentials are invalid it will throw a 401 error. The middleware will call options.authenticationFunction with the username and password it gets from the basic auth header.

JWT authentication

There are two JWT authentication middlewares: verifyTokenAuth() and setTokenAuth().

verifyTokenAuth() validates a JWT in a header. If the credentials are valid the authenticated user will be copied into response.locals.user and if the credentials are invalid it will throw a 401 error. The middleware will call options.authenticationFunction with a username (the sub claim of the JWT) and no password.

setTokenAuth() creates a JWT and sets it in a response header. The json web token sub claim is response.locals.user.username. It will throw a 500 error if there is any problem creating the token.

Role authorization

allowRoles() checks if the authenticated user has one of the required roles. If it does not it will throw a 403 error. The middleware will call options.authorizationFunction with the user in response.locals.user and the requested roles.

Skipping middleware routes

The nextRouteIfUnauthorized() and nextRouteIfForbidden() middlewares skip to the next middleware route if they receive a 401 and 403 errors respectively. They can be used to have both a private and a public version of the same route, or different versions of the same route for different roles.

Sending the user

sendUser() sends the user in response.locals.user as the response body or throws a 500 if there is no user in response.locals.

Options

The verifyBasicAuth(), verifyTokenAuth(), setTokenAuth() and allowRoles() functions use the following options:

export interface AuthenticationFunction {
  (username: string, password?: string): Promise<object | undefined>; // return the user if it is valid or undefined if not
}

export interface AuthorizationFunction<User extends object, Role extends string> {
  (user: User, ...roles: Role[]): boolean; // return whether the user has one of the requested roles
}

export interface BasicAuthenticationOptions {
  authenticationFunction: AuthenticationFunction; // will be called with both username and password
}

export interface TokenAuthenticationOptions {
  authenticationFunction: AuthenticationFunction; // will be called with only the username, since the JWT will already be valid
  jwtSigningSecret: string; // the secret to sign and verify JWT
  headerName: string; // the name of the header to use for the JWT, e.g. x-access-token
  expiresIn?: number; // if set the JWT will expire in X seconds
}

export interface AuthorizationOptions<User extends object, Role extends string> {
  authorizationFunction: AuthorizationFunction<User, Role>;
}

Each of the above functions actually receives either a regular object of the above types, or a function that receives the request and response and returns an options object:

type Resolver<T> = T | ((request: Request, response: Response) => T);

function verifyBasicAuth(options: Resolver<BasicAuthenticationOptions>): RequestHandler;
function verifyTokenAuth(options: Resolver<TokenAuthenticationOptions>): RequestHandler;
function setTokenAuth(options: Resolver<TokenAuthenticationOptions>): RequestHandler;
function allowRoles<User extends object, Role extends string>(options: Resolver<AuthorizationOptions<User, Role>>,): (...roles: Role[]) => RequestHandler;

The functional form of the options can be used to dynamically decide which options to use, for example:

  • Allowing only certain roles to log in depending on the origin of the request, like a website only for admin users.
  • Using different JWT header names depending on the origin of the request, allowing users to log in simultaneously with multiple accounts.
  • Returning a JWT with a different expiration depending on the role of the user.