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

@riavzon/auth-h3client

v2.0.1

Published

H3 middleware, routes and client utilities for the Riavzon Auth service - includes magic links, OAuth/OIDC helpers, CSRF issuance/verification, token management, and optional mTLS support.

Downloads

3,016

Readme

auth-H3Client

H3 middleware, controllers, and utilities for integrating the front-end gateway with the auth service. Pairing this package with an auth service instance (using its default or custom configuration) gives you end-to-end authentication flows with minimal wiring.

Features

  • Drop-in routes: useAuthRoutes, magicLinksRouter, and useOAuthRoutes register login, signup, MFA, reset-password, and OAuth flows on any H3 router.
  • Middlewares: CSRF issuance/verification, body size limiting, visitor fingerprint validation, token rotation, structured logging, and more.
  • Typed utilities: Cookie helpers, PKCE generation, OAuth token verification, server-to-server fetch wrapper, and mini cache implementation.
  • Config-driven: Strongly typed configuration schema validated via zod, with optional OAuth provider metadata, HMAC signing, and TLS options.

Installation

npm install @riavzon/auth-h3client

Nuxt 3+ Module

If you are using Nuxt 3++, use the dedicated module. It handles all configuration, middleware, and auto-imports for you.

  1. Install:
    npm install @riavzon/auth-h3client
  2. Add to nuxt.config.ts:
    modules: ['@riavzon/auth-h3client/module'],
  3. Read the Nuxt Module Documentation for full configuration and usage.

H3 v1 vs v2

This package supports both H3 v1 and H3 v2. Choose the matching entry point for your H3 version:

  • H3 v1 (default): import from @riavzon/auth-h3client or @riavzon/auth-h3client/v1 (peer: h3@^1.15.4).
  • H3 v2: import from @riavzon/auth-h3client/v2 (peer: h3@^2.0.0-beta.4).
  • Client: import from @riavzon/auth-h3client/client for Nuxt/Vue composables (peer: nuxt, vue, ofetch).

Quick wiring examples:

  • H3 v1

    import { createApp, createRouter } from 'h3'
    import { configuration, httpLogger, isIPValid, botDetectorMiddleware, generateCsrfCookie, useAuthRoutes, magicLinksRouter, useOAuthRoutes } from '@riavzon/auth-h3client/v1'
    configuration({ /* ... */ })
    const app = createApp()
    httpLogger()(app)
    app.use(isIPValid)
    app.use(botDetectorMiddleware)
    app.use(generateCsrfCookie)
    const router = createRouter()
    useAuthRoutes(router); magicLinksRouter(router); useOAuthRoutes(router)
    app.use(router)
  • H3 v2

    import { createApp, createRouter } from 'h3'
    import { configuration, httpLogger, isIPValid, botDetectorMiddleware, generateCsrfCookie, useAuthRoutes, magicLinksRouter, useOAuthRoutes } from '@riavzon/auth-h3client/v2'
    configuration({ /* ... */ })
    const app = createApp()
    app.use(httpLogger)
    app.use(isIPValid)
    app.use(botDetectorMiddleware)
    app.use(generateCsrfCookie)
    const router = createRouter()
    useAuthRoutes(router); magicLinksRouter(router); useOAuthRoutes(router)
    app.use(router)

See docs/h3-v1-v2.md for more details, including route-level middleware and handler differences.

Configuring the Library

Before using any exported handlers you must call the configuration function exactly once at boot. The settings mirror Configuration from src/types/configSchema.ts.

import { configuration } from '@riavzon/auth-h3client';
import { createStorage } from 'unstorage';
import memoryDriver from 'unstorage/drivers/memory';

const storage = createStorage({ driver: memoryDriver() });

configuration({
  server: {
    auth_location: {
      serverOrDNS: process.env.AUTH_API_HOST ?? '127.0.0.1',
      port: Number(process.env.AUTH_API_PORT ?? 10000),
    },
    hmac: {
      enableHmac: true,
      clientId: process.env.AUTH_CLIENT_ID!,
      sharedSecret: process.env.AUTH_SHARED_SECRET!,
    },
    ssl: {
      enableSSL: false,
    },
    cryptoCookiesSecret: process.env.COOKIE_SECRET!,
  },
  uStorage: {
    storage: storage,
    cacheOptions: {
      successTtl: 60 * 60 * 24 * 30,  // 30 days
      rateLimitTtl: 10
    }
  },
  onSuccessRedirect: 'https://app.example.com/dashboard',
  OAuthProviders: [
    {
      kind: 'oidc',
      name: 'google',
      issuer: 'https://accounts.google.com',
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
      defaultScopes: ['openid', 'email', 'profile'],
      redirectUri: 'https://app.example.com/oauth/callback/google',
      supportPKCE: true,
      redirectUrlOnSuccess: 'https://app.example.com/dashboard',
      redirectUrlOnError: 'https://app.example.com/login',
    },
  ],
  logLevel: 'info',
});

Providers quick reference

You can mix and match both kinds under OAuthProviders.

OIDC provider shape (discriminated by kind: 'oidc'):

{
  kind: 'oidc';
  name: string;                         // short provider key used in routes
  issuer: string;                       // https://... OIDC issuer URL
  clientId: string;
  clientSecret: string;
  redirectUri: string;                  // where the provider redirects back
  supportPKCE: boolean;                 // whether to use PKCE
  redirectUrlOnSuccess: string;         // http(s)://...
  redirectUrlOnError: string;           // http(s)://...
  // optional
  defaultScopes?: string[];             // e.g. ['openid','email','profile']
  extraAuthParams?: Record<string,string>; // idp-specific extra params
  tokenAuthMethod?: 'client_secret_basic' | 'client_secret_post';
}

OAuth provider shape (discriminated by kind: 'oauth'):

{
  kind: 'oauth';
  name: string;                         // short provider key used in routes
  authorizationEndpoint: string;        // https://.../authorize
  tokenEndpoint: string;                // https://.../token
  userInfoEndpoint: string;             // https://.../userinfo
  clientId: string;
  clientSecret: string;
  redirectUri: string;
  supportPKCE: boolean;
  redirectUrlOnSuccess: string;         // http(s)://...
  redirectUrlOnError: string;           // http(s)://...
  // optional
  defaultScopes?: string[];
  extraAuthParams?: Record<string, string>;
  tokenAuthMethod?: 'client_secret_basic' | 'client_secret_post';
  emailCallBack?: (accessToken: string) => Promise<string>; // when provider lacks email
  extraUserInfoCallBacks?: Array<(accessToken: string) => Promise<Record<string,unknown>>>; // merge extra user data
}

Complete configuration example

Below is a single, complete configuration object showing all fields. Items marked as optional are not required and can be omitted.

// config/auth-client.config.ts
import type { Configuration } from '@riavzon/auth-h3client/dist/types/configSchema';
import { createStorage } from 'unstorage';
import memoryDriver from 'unstorage/drivers/memory';

const storage = createStorage({ driver: memoryDriver() });

export const config: Configuration = {
  server: {
    auth_location: {
      serverOrDNS: '127.0.0.1',
      port: 10000,
    },
    // Optional HMAC sealing – set enableHmac to false to disable
    hmac: {
      enableHmac: true,
      clientId: process.env.AUTH_CLIENT_ID!,
      sharedSecret: process.env.AUTH_SHARED_SECRET!,
    },
    // Optional mTLS – set enableSSL to false if not using client certs
    ssl: {
      enableSSL: false, // true if mutual TLS is required by your auth service
      // The following paths are required only when enableSSL is true
      // (optional when enableSSL is false)
      mainDirPath: '/etc/ssl',           // optional
      rootCertsPath: 'rootCA.pem',       // optional
      clientCertsPath: 'client.crt',     // optional
      clientKeyPath: 'client.key',       // optional
    },
    cryptoCookiesSecret: process.env.COOKIE_SECRET!,
  },

  // Storage for caching user authentication data (required)
  uStorage: {
    storage: storage,  // any unstorage driver: memory, redis, cloudflare-kv, etc.
    cacheOptions: {
      successTtl: 60 * 60 * 24 * 30,  // 30 days
      rateLimitTtl: 10                 // 10 seconds
    }
  },

  // Where users are redirected after successful auth (used by multiple flows)
  onSuccessRedirect: 'https://app.example.com/dashboard',

  // Optional list of OAuth/OIDC providers
  OAuthProviders: [
    {
      kind: 'oidc',
      name: 'google',
      issuer: 'https://accounts.google.com',
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
      redirectUri: 'https://app.example.com/oauth/callback/google',
      supportPKCE: true,
      redirectUrlOnSuccess: 'https://app.example.com/dashboard',
      redirectUrlOnError: 'https://app.example.com/login',
      // optional
      defaultScopes: ['openid', 'email', 'profile'],
      extraAuthParams: {
        access_type: 'offline',
        prompt: 'consent',
      },
      tokenAuthMethod: 'client_secret_basic', // optional
    },
    {
      kind: 'oauth',
      name: 'github',
      authorizationEndpoint: 'https://github.com/login/oauth/authorize',
      tokenEndpoint: 'https://github.com/login/oauth/access_token',
      userInfoEndpoint: 'https://api.github.com/user',
      clientId: process.env.GITHUB_CLIENT_ID!,
      clientSecret: process.env.GITHUB_CLIENT_SECRET!,
      redirectUri: 'https://app.example.com/oauth/callback/github',
      supportPKCE: true,
      redirectUrlOnSuccess: 'https://app.example.com/dashboard',
      redirectUrlOnError: 'https://app.example.com/login',
      // optional
      defaultScopes: ['read:user', 'user:email'],
      emailCallBack: async (accessToken) => {
        // Fetch primary email from provider API if needed
        // return string email
        return '[email protected]';
      },
      extraUserInfoCallBacks: [
        async (accessToken) => ({ timezone: 'UTC' }),
      ],
      tokenAuthMethod: 'client_secret_post', // optional
      extraAuthParams: { include_granted_scopes: 'true' }, // optional
    },
  ],


  // Logger level used by internal pino
  logLevel: 'info', // 'debug' | 'info' | 'warn' | 'error' | 'fatal'
};

Configuration cheat sheet

| Key | Description | | --- | --- | | server.auth_location | Location of the upstream auth API (host & port). | | server.hmac | Enables optional HMAC sealing of outbound requests; requires client ID and shared secret. | | server.ssl | TLS settings for mutual TLS connections to the auth API. When enableSSL is true, provide certificate paths. | | server.cryptoCookiesSecret | Secret used to sign CSRF and state cookies. | | onSuccessRedirect | Default redirect URL after successful login/signup/MFA flows. | | OAuthProviders | Optional list of OAuth/OIDC providers with per-provider redirect behavior. | | logLevel | Pino logger level (debug, info, warn, error, or fatal). |

See test/setup/config.ts for a complete example with multiple OAuth providers.

H3 Application

The library exports controllers, middlewares, and route registrars. A typical setup looks like:

import { H3, serve } from 'h3';
import {
  configuration,
  httpLogger,
  isIPValid,
  botDetectorMiddleware,
  generateCsrfCookie,
  useAuthRoutes,
  magicLinksRouter,
  useOAuthRoutes,
} from '@riavzon/auth-h3client';

configuration(/* ...config object from above... */);

const app = new H3();
app.register(httpLogger());
app.use(isIPValid);
// Wire the bot detector only if your auth service enables it (/check endpoint)
app.use(botDetectorMiddleware);
app.use(generateCsrfCookie);

useAuthRoutes(app);
magicLinksRouter(app);
useOAuthRoutes(app);

serve(app, {
  port: 3000,
  hostname: '0.0.0.0',
});

Using individual controllers/middlewares

Every piece is exportable if you prefer composing your own routes:

import { defineEventHandler } from 'h3';
import {
  loginHandler,
  handleLogout,
  limitBytes,
  verifyCsrfCookie,
  ensureValidCredentials,
} from '@riavzon/auth-h3client';

router.post(
  '/auth/login',
  loginHandler,
  { middleware: [verifyCsrfCookie, limitBytes(1024)] },
);

router.post(
  '/auth/logout',
  handleLogout,
  { middleware: [verifyCsrfCookie, ensureValidCredentials] },
);

Utilities and Helpers

  • serviceToService (alias of sendToServer): wraps fetch with client headers, cookies, and optional HMAC signing.
  • makeCookie, createSignedValue, verifySignedValue: consistent cookie helpers respecting __Host- / __Secure- prefixes.
  • ensureAccessToken, ensureRefreshCookie, ensureValidCredentials: token rotation middleware for protecting downstream routes.
  • verifyOAuthToken, discoverOidc, makePkcePair: OAuth/OIDC support primitives.
  • MiniCache: lightweight TTL cache useful for memoizing remote lookups.

Refer to the TSDoc comments across src/ for parameter descriptions and usage samples.

Full docs available here https://docs.riavzon.com/docs/auth-h3client