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

@digistra/auth

v3.0.5

Published

Modular auth package for Digistra apps

Downloads

1,753

Readme

@digistra/auth

Runtime auth SDK for Digistra applications.

This package provides route protection, session helpers, server and mock adapters, Next.js middleware integration, and minimal React UI primitives.

Who This Is For

  • Frontend developers integrating Digistra auth flows.
  • Teams that want predictable route gating in Next.js.
  • AI agents that need code-accurate guidance for auth integration.

What This Package Is (And Is Not)

This package is:

  • A runtime SDK (defineDigistraAuth, login, logout, getSession, checkAuth)
  • Adapter-driven (server adapter, mock adapter, custom adapters)
  • Compatible with Next middleware and simple UI primitives

This package is not:

  • A full identity provider
  • A complete authorization policy engine
  • The backend auth service itself

Install

npm install @digistra/auth

Compatibility

  • next: >=13.0.0 (peer)
  • react: >=18.0.0 (peer)
  • react-dom: >=18.0.0 (peer)

Exports

@digistra/auth

  • defineDigistraAuth
  • createDigistraAuthServerAdapter
  • DIGISTRA_AUTH_SERVER_BASE_URL
  • login, logout, getSession, checkAuth
  • Core types (DefineDigistraAuthConfig, DigistraAuthAdapter, etc.)

@digistra/auth/mock

  • mockAdapter
  • mockAdapterByEnv
  • loadMockUsers
  • seedAuthStoreFromFile
  • seedAuthStoreFromData

@digistra/auth/next

  • createDigistraMiddleware

@digistra/auth/ui

  • LoginForm
  • AuthOverlay

Commands

Package Development Commands (this repository)

npm run build
npm run clean
npm pack --dry-run

Platform CLI Commands (npx digistra ...)

There is currently no dedicated @digistra/auth CLI command surface in this package itself.

If your broader Digistra platform exposes auth-related CLI commands, treat those as external tooling (outside this package API contract).

Quick Start

import { defineDigistraAuth, createDigistraAuthServerAdapter, login, checkAuth } from "@digistra/auth";

defineDigistraAuth({
	publicRoutes: ["/", "/login", "/public/*"],
	privateRoutes: ["/dashboard/*", "/cms/*"],
	unauthorizedRedirect: "/login",
	adapter: createDigistraAuthServerAdapter({
		baseUrl: "https://auth.digistra.dev",
	}),
});

const loggedIn = await login({
	identifier: "admin",
	password: "admin123",
});

const allowed = await checkAuth({
	pathname: "/dashboard/settings",
	checkOnly: true,
});

Configuration

defineDigistraAuth(config)

Registers global auth config as singleton.

Required fields:

  • publicRoutes
  • privateRoutes
  • unauthorizedRedirect
  • adapter

Important behavior:

  • privateRoutes always win over publicRoutes
  • Calling helpers before configuration throws

Core Runtime API

login({ identifier, password })

  • Input key is identifier (not credential)
  • Returns true for valid credentials, false otherwise
  • Headless behavior: no automatic redirect

logout()

  • Calls adapter logout when available
  • Always clears local session state afterwards

getSession()

  • Returns adapter session when adapter provides getSession
  • Falls back to local session read otherwise
  • Returns null when unauthenticated

checkAuth({ pathname?, status?, checkOnly? })

Defaults:

  • checkOnly defaults to true

Unauthorized conditions:

  • status === 401
  • Private route without valid session/check

Behavior:

  • checkOnly: true -> returns boolean, no redirect
  • checkOnly: false -> in browser, redirects to unauthorizedRedirect on unauthorized

Route Matching

Route matching is case-sensitive and supports:

  • * / /* (match all)
  • Exact paths (example: /login)
  • Prefix wildcards (example: /dashboard/*)
  • Mixed wildcard patterns (example: /a/*/b)

Trailing slashes are normalized (/dashboard equals /dashboard/).

Bearer Token Architecture (Production)

In production, @digistra/auth operates on a Zero-Touch Bearer token model. You do not manage tokens manually — the SDK handles storage, injection, and refresh internally.

How it works

Browser  ──POST /login──►  Server Action (loginWithServer)
                                │
                                ▼ receives { accessToken, refreshToken }
                                │
                        storeServerTokenPair()
                                │
                                ▼ next/headers cookies.set()
Response  ◄── Set-Cookie: ds_at=<jwt>; HttpOnly; Secure; SameSite=Strict
              Set-Cookie: ds_rt=<jwt>; HttpOnly; Secure; SameSite=Strict
                                │
Next Request ──Cookie: ds_at=...──► Edge Middleware (createDigistraMiddleware)
                                        │  reads ds_at → isAuthenticated = true
                                        ▼
                               Server Component / Server Action
                               readServerTokenPair() → ds_at
                               fetch(..., { Authorization: "Bearer <at>" })
  • ds_at — Access token. HttpOnly; Secure; SameSite=Strict; MaxAge=15min
  • ds_rt — Refresh token. HttpOnly; Secure; SameSite=Strict; MaxAge=7days
  • Both cookies are HttpOnly (no JS access) and sent automatically in the Cookie header on every request, making them readable by the Edge Middleware and Next.js Server functions.
  • On token expiry the SDK performs an automatic 401-refresh loop: exchanges ds_rt for a new ds_at, updates the cookie in the current response, and retries the original request — all transparently.

Dev vs Prod toggle

| Environment | Auth check in middleware | Token storage | |---|---|---| | development | dsid cookie or digistra_auth_session mock cookie | File-backed mock session | | production | ds_at HttpOnly cookie | next/headers server cookies |

Internal cookie API

These are exported for use by @digistra/cms and advanced integrations. Normal application code should never call them directly.

import { readServerTokenPair, updateServerAccessToken, DIGISTRA_REFRESH_TOKEN_COOKIE } from "@digistra/auth";
  • readServerTokenPair() — reads ds_at + ds_rt from next/headers cookies
  • updateServerAccessToken(at) — updates ds_at in next/headers cookies (used after refresh)
  • DIGISTRA_REFRESH_TOKEN_COOKIE — the cookie name "ds_rt"

Server Adapter

createDigistraAuthServerAdapter(options?)

Defaults:

  • Base URL: https://auth.digistra.dev
  • loginPath: /login
  • logoutPath: /logout
  • sessionPath: /session
  • refreshPath: /refresh

Semantics:

  • login — POSTs credentials, captures { accessToken, refreshToken } from JSON response, stores in ds_at/ds_rt HttpOnly cookies via next/headers.
  • check / getSession — reads Bearer token from server cookies, retries automatically after 401 with refresh token.
  • logout — revokes refresh token on server, clears both ds_at and ds_rt cookies.

Mock Adapters

mockAdapter({ users?, file? })

  • Supports inline users and optional JSON file users
  • Uses identifier to match against user.credential
  • Requires stored password for successful auth in mock mode

mockAdapterByEnv(options)

Behavior:

  • Defaults to mock mode unless NODE_ENV === "production"
  • When file option is provided (Node.js environment):
    • Reads and writes user data to {file}/users.json
    • All reads/writes persist to disk (multi-process safe)
    • Perfect for development with Next.js App Router + Turbopack
    • Changes visible immediately across tabs/sessions
  • In non-mock mode:
    • Uses fallbackAdapter when provided
    • Otherwise uses createDigistraAuthServerAdapter({ baseUrl: authServerBaseUrl })

Example with file-backed storage:

import { defineDigistraAuth } from "@digistra/auth";
import { mockAdapterByEnv } from "@digistra/auth/mock";

defineDigistraAuth({
	publicRoutes: ["/", "/login"],
	privateRoutes: ["/dashboard/*"],
	unauthorizedRedirect: "/login",
	adapter: mockAdapterByEnv({
		file: "node_modules/.digistra/auth",
	}),
});

This will:

  1. Create node_modules/.digistra/auth/users.json on first use
  2. Read/write users to this file on every auth operation
  3. Share user data across processes in development

seedAuthStoreFromFile(seedPath, targetDir) & seedAuthStoreFromData(users, targetDir)

Helper functions to initialize auth store from seed files:

  • seedAuthStoreFromFile(seedPath, targetDir) - Load users from JSON file
  • seedAuthStoreFromData(users, targetDir) - Create store from data array
  • Useful for bootstrapping .digistra/auth/ on app startup or reset

Example:

import { seedAuthStoreFromFile } from "@digistra/auth/mock";

// Initialize auth store from seed
await seedAuthStoreFromFile("./seed-auth.json", "node_modules/.digistra/auth");

Seed JSON format:

{
	"users": [
		{
			"id": "user-1",
			"name": "Test User",
			"credential": "[email protected]",
			"password": "password123"
		}
	]
}

loadMockUsers(options)

  • Merges inline users + file users
  • De-duplicates by id, fallback key credential
  • File loading is server-only (throws in browser)

Next.js Integration

createDigistraMiddleware()

Protects private routes and redirects unauthenticated requests. Runs in the Next.js Edge Runtime — zero server overhead.

// middleware.ts
import { createDigistraMiddleware } from "@digistra/auth/next";

export default createDigistraMiddleware();

export const config = {
	matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
};

Behavior by environment:

| | Development | Production | |---|---|---| | Auth signal | dsid cookie or digistra_auth_session mock cookie | ds_at cookie (HttpOnly, set by the SDK after login) | | On failure | Redirect to unauthorizedRedirect | Redirect to unauthorizedRedirect |

  • No config loaded → no-op (NextResponse.next())
  • Cookie check is header-only — no network calls in middleware.

UI Components

LoginForm

LoginForm emits { credential, password } in onSubmit.

If you call core login(...), map credential to identifier:

"use client";

import { login } from "@digistra/auth";
import { LoginForm } from "@digistra/auth/ui";

export function LoginPage() {
	return <LoginForm onSubmit={({ credential, password }) => login({ identifier: credential, password })} />;
}

AuthOverlay

  • Resolves session on mount
  • Renders children if authorized, otherwise fallback

Session Model

Development cookies

| Cookie | Set by | Purpose | |---|---|---| | digistra_auth_session | Mock adapter (browser) | Base64-encoded session JSON | | dsid | Real auth server | Opaque server session indicator |

Production cookies (internal SDK state)

| Cookie | Set by | Attributes | Purpose | |---|---|---|---| | ds_at | loginWithServer via next/headers | HttpOnly; Secure; SameSite=Strict; MaxAge=15min | Access token — read by Edge Middleware and server fetches | | ds_rt | loginWithServer via next/headers | HttpOnly; Secure; SameSite=Strict; MaxAge=7days | Refresh token — used to obtain a new ds_at on expiry |

Notes:

  • HttpOnly cookies are never accessible to JavaScript; they are sent automatically in the Cookie header on every browser request.
  • The Edge Middleware (createDigistraMiddleware) reads ds_at from the raw cookie header — no JS or next/headers required at that layer.
  • After a successful token refresh, the updated ds_at is written back via next/headers in the same server response cycle.

Error Handling Pattern

Use explicit boolean checks instead of assuming exceptions for auth failures:

const ok = await login({ identifier, password });
if (!ok) {
	// invalid credentials or auth backend unavailable
}

For protected fetches:

const response = await fetch("/api/private", { credentials: "include" });
await checkAuth({ status: response.status, checkOnly: false });

Development & Testing

Manual Testing with dev-app

A complete Next.js test application is available at ../dev-app/ for manual testing:

cd ../dev-app
npm run reset       # Initialize .digistra/auth with seed data
npm run dev         # Start dev server

Test scenarios:

  • Login page (/login) - Try test credentials
  • Multi-session sync - Open login in 2 tabs, verify same users
  • Data persistence - Refresh page, data persists
  • Reset script - Run npm run reset to clear and re-seed

Testing workflows documented in: ../dev-app/README.md

File-Based Storage in Development

The file-backed mock adapter enables:

  • Real-time sync across multiple tabs/windows
  • Persistent storage in node_modules/.digistra/auth/users.json
  • Cross-process safety in Next.js Turbopack dev environment
  • Easy reset via npm run reset script

For AI Agents

When generating code with this package:

  • Always initialize once with defineDigistraAuth(...) before helper usage
  • Use identifier in core login, not credential
  • Treat false return values as expected auth outcomes (not always exceptional errors)
  • Keep route examples consistent with private-route precedence
  • In UI examples, map LoginForm credential field to core login identifier
  • For development/testing, use mockAdapterByEnv({ file: "path" }) for file-backed persistence

License

MIT