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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@thekid000/auth-basic-improve

v1.0.1

Published

node.js basic auth parser

Readme

@thekid000/auth-basic-improve

License: MIT Node.js >= 24 TypeScript

A lightweight, TypeScript-native Basic Authentication parser for Node.js & Express.js.

Supports static user validation, custom synchronouss/async authorizers, timing-safe comparisons, and configurable challenge headers.


Table of Contents


Features

  • Core Parser: Extract username and password from base64-encoded Basic Auth headers.
  • Express Middleware: Drop-in authentication middleware for Express.js routes.
  • Timing-Safe Comparison: Prevents timing attacks via timingSafeEqual.
  • Flexible Authorizers: Use static user lists, sync, or async custom functions.
  • Challenge Mode: Send WWW-Authenticate headers for browser pop-ups.
  • Custom Responses: Return static strings, JSON, or dynamic messages on 401.
  • Fully Typed: 100% TypeScript with exported interfaces.

Installation

# Using Yarn (recommended, packageManager: [email protected])
yarn add @thekid000/auth-basic-improve

# Using npm
npm install @thekid000/auth-basic-improve

Requirements: Node.js >= 24


Usage

1. Parse Basic Auth String

Extract credentials directly from a base64-encoded string:

import { parse } from "@thekid000/auth-basic-improve";

const result = parse("Basic Zm9vOmJhcg==");
// Returns: { name: "foo", pass: "bar" }
// Returns undefined for invalid/malformed header strings
// Throws TypeError if the input is not a string

2. Extract Auth from Express Request

Parse the Authorization header from an Express Request object:

import { auth } from "@thekid000/auth-basic-improve";

app.get("/protected", (req, res) => {
  const credentials = auth(req);

  if (!credentials) {
    return res.status(401).send("Unauthorized");
  }

  console.log(credentials.name); // "foo"
  console.log(credentials.pass); // "bar"
  res.send("Authenticated!");
});

3. Express Middleware

Build a full authentication middleware with the named buildMiddleware export:

import { buildMiddleware } from "@thekid000/auth-basic-improve";

Static Users

Define users directly in the options:

const authMiddleware = buildMiddleware({
  challenge: false,
  users: { Admin: "secret1234", User: "password123" },
});

app.get("/admin", authMiddleware, (req, res) => {
  res.send("Welcome, Admin!");
});

Custom Synchronous Authorizer

Provide your own validation logic:

const myAuthorizer = (username: string, password: string): boolean => {
  // e.g., query a database
  return username.startsWith("A") && password.startsWith("secret");
};

const authMiddleware = buildMiddleware({ authorizer: myAuthorizer });

Custom Asynchronous Authorizer

For database lookups or async operations:

const myAsyncAuthorizer = (
  username: string,
  password: string,
  cb: (err: Error | null, result: boolean) => void
): void => {
  // Simulate async DB query
  db.findUser(username, (err, user) => {
    if (err) return cb(err, false);
    cb(null, user && user.password === password);
  });
};

const authMiddleware = buildMiddleware({
  authorizeAsync: true,
  authorizer: myAsyncAuthorizer,
});

Challenge Mode

Send a WWW-Authenticate header to trigger browser credential prompts:

const authMiddleware = buildMiddleware({
  challenge: true,
  users: { Admin: "secret1234" },
});
// On 401, response includes: WWW-Authenticate: Basic realm="..."

Custom realm:

const authMiddleware = buildMiddleware({
  challenge: true,
  realm: "My Protected Area",
  users: { Admin: "secret1234" },
});
// Response: WWW-Authenticate: Basic realm="My Protected Area"

Custom Response Body

Control the 401 response content:

// Static string
const authMiddleware = buildMiddleware({
  unauthorizedResponse: "Access Denied",
});

// JSON object
const authMiddleware = buildMiddleware({
  unauthorizedResponse: { error: "Unauthorized", code: 401 },
});

// Dynamic function
const authMiddleware = buildMiddleware({
  unauthorizedResponse: (req) =>
    req.auth
      ? `Credentials ${req.auth.user}:${req.auth.password} rejected`
      : "No credentials provided",
  users: { Foo: "bar" },
});

Safe Compare

Use timing-safe byte comparison to reduce content-dependent timing differences:

import { safeCompare } from "@thekid000/auth-basic-improve";

const myAuthorizer = (username: string, password: string): boolean => {
  return (
    safeCompare(username, "ExpectedUser") &&
    safeCompare(password, "ExpectedPass")
  );
};

API Reference

parse(str: string) => Credentials | undefined

Parses a base64-encoded Basic Authentication string into { name, pass }.

| Parameter | Type | Required | Description | | --------- | -------- | -------- | --------------------- | | str | string | Yes | Base64-encoded auth string |

Returns: { name: string, pass: string } on success, undefined for malformed or non-Basic header strings.

Throws: TypeError if str is not a string.


auth(req: Request) => Credentials | undefined

Extracts and parses the Authorization header from an Express request.

| Parameter | Type | Required | Description | | --------- | --------- | -------- | ---------------------- | | req | Request | Yes | Express request object |

Returns: { name: string, pass: string } on success, undefined on failure.


buildMiddleware(options: IbuildMiddleware) => (req, res, next) => void

Creates an Express authentication middleware.

| Option | Type | Default | Description | | --------------------- | ------------------ | ---------------- | ------------------------------------ | | challenge | boolean | false | Send WWW-Authenticate header | | users | Record<string, string> | {} | Static username → password map | | authorizer | function | — | Custom validation function | | authorizeAsync | boolean | false | Enable async authorizer | | unauthorizedResponse| unknown | "" | Custom 401 response body | | realm | string \| function | undefined | Custom realm string or generator |


safeCompare(userInput: string, secret: string) => boolean

Compares strings using crypto.timingSafeEqual, avoiding an early exit when bytes differ. Runtime still depends on the longer input's byte length, so it is not constant-time across different input lengths.


Project Structure

src/
├── index.ts                        # Main entry point — re-exports everything
├── app.ts                          # Aggregates core auth module
├── basicAuth/
│   ├── index.ts                    # Core parser: parse() & auth()
│   └── base64.ts                   # Base64 encode/decode utilities
├── expressBasicAuth/
│   └── index.ts                    # Express middleware builder
└── interfaces/
    ├── basicAuth.interface.ts      # Credentials, IRequestHeaderAuthorization
    └── expressBasicAuth.interface.ts # IBasicAuthedRequest, IbuildMiddleware

tests/
├── unit/
│   ├── basicAuth.test.ts           # Unit tests for parse() & auth()
│   ├── base64.spec.ts              # Unit tests for base64 encode/decode
│   ├── format.spec.ts              # Unit tests for format() (header formatting)
│   └── safeCompare.spec.ts         # Unit tests for safeCompare()
├── integration/
│   └── expressBasicAuth.test.ts    # Integration tests for middleware
└── benchmarks/
    ├── base64.bench.ts             # Benchmarks for base64 decoding strategies
    ├── format.bench.ts             # Benchmarks for format() performance
    └── parse.bench.ts              # Benchmarks for parse() performance

See README_STRUCTURE.md for a detailed file-by-file breakdown.


Development

# Install dependencies
yarn install

# Build TypeScript → JavaScript
yarn build

# Run tests
yarn test

# Run tests with coverage
yarn test:coverage

# Run unit tests only
yarn test:unit

# Lint & fix
yarn lint

# Bundle size check
yarn size

License

MIT © Tri Bui Quang