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

sdk-simple-auth

v2.6.0

Published

Universal JavaScript/TypeScript authentication SDK with multi-backend support, automatic token refresh, and React integration

Readme

sdk-simple-auth

npm License TypeScript

Universal JavaScript/TypeScript authentication SDK with multi-backend support, automatic token refresh, and React integration.


Features

  • Multi-backend — works out of the box with Node.js/Express, Laravel Sanctum, and standard JWT
  • Auto-detection — analyzes your API response and configures itself automatically
  • React hook — useAuth() with full state management
  • Auto token refresh — refreshes tokens before they expire, configurable buffer time
  • Encrypted storage — optional AES-GCM 256-bit encryption at rest
  • Axios interceptors — drop-in AxiosInterceptorManager for automatic auth headers
  • Session validation — SessionValidator with expiry tracking and session IDs
  • Multi-tab sync — optional BroadcastChannel sync: login/logout/token-refresh propagated to all open tabs
  • Flexible storage — localStorage, IndexedDB, or in-memory
  • TypeScript — full types, tree-shakeable ESM + CJS + UMD builds

Installation

npm install sdk-simple-auth

Quick Start

Node.js / Express

import { createQuickNodeAuth } from 'sdk-simple-auth';

const auth = createQuickNodeAuth('http://localhost:3000');

const user = await auth.login({ email: '[email protected]', password: 'secret' });

Laravel Sanctum

import { createQuickSanctumAuth } from 'sdk-simple-auth';

const auth = createQuickSanctumAuth('http://localhost:8000/api');

const user = await auth.login({ email: '[email protected]', password: 'secret' });

Auto-detect from response

import { quickAnalyzeAndCreate } from 'sdk-simple-auth';

// Pass a sample response from your API and it configures itself
const auth = quickAnalyzeAndCreate(sampleApiResponse, 'http://localhost:3000');

Manual configuration

import { AuthSDK } from 'sdk-simple-auth';

const auth = new AuthSDK({
  authServiceUrl: 'http://localhost:3000',
  endpoints: {
    login: '/auth/login',
    register: '/auth/register',
    refresh: '/auth/refresh',
    logout: '/auth/logout',
  },
  backend: {
    type: 'node-express',       // 'node-express' | 'laravel-sanctum' | 'jwt-standard'
    userSearchPaths: ['user', 'data.user'],
    fieldMappings: {
      userId: ['id', 'user_id'],
      email: ['email'],
      name: ['name', 'full_name'],
    },
  },
  storage: {
    type: 'localStorage',       // 'localStorage' | 'indexedDB'
  },
  tokenRefresh: {
    enabled: true,
    bufferTime: 900,            // Refresh 15 min before expiry
    maxRetries: 3,
  },
});

Core API

// Auth
await auth.login(credentials)
await auth.register(userData)
await auth.logout()
await auth.isAuthenticated()
auth.getCurrentUser()

// Tokens
await auth.getValidAccessToken()
await auth.getAuthHeaders()       // { Authorization: 'Bearer ...' }
await auth.refreshTokens()
await auth.forceRefreshTokens()

// Session
await auth.getSessionInfo()       // { isValid, refreshAvailable, sessionId }
await auth.getExtendedSessionInfo()

// State
auth.getState()
auth.onAuthStateChanged((state) => { ... })

// Lifecycle
auth.destroy()                    // stop listeners/timers before discarding instance

// Debug
auth.debugToken()
auth.debugResponse(response)
auth.debugSession()

React Hook

import { AuthSDK, useAuth } from 'sdk-simple-auth';

const authSDK = new AuthSDK({ authServiceUrl: 'http://localhost:3000' });

function App() {
  const {
    isAuthenticated,
    user,
    loading,
    error,
    sessionInfo,
    login,
    logout,
    getAuthHeaders,
  } = useAuth(authSDK);

  if (loading) return <p>Loading...</p>;

  return isAuthenticated ? (
    <div>
      <p>Hello, {user?.name}</p>
      <button onClick={logout}>Logout</button>
    </div>
  ) : (
    <button onClick={() => login({ email: '[email protected]', password: 'secret' })}>
      Login
    </button>
  );
}

Axios Interceptors

Automatically attaches auth headers and handles 401 token refresh on every request:

import axios from 'axios';
import { AuthSDK, AxiosInterceptorManager } from 'sdk-simple-auth';

const auth = new AuthSDK({ authServiceUrl: 'http://localhost:3000' });
const client = axios.create({ baseURL: 'http://localhost:3000' });

const interceptors = new AxiosInterceptorManager(auth, client);
interceptors.setup();

// All requests now include Authorization header automatically
// 401 responses trigger a token refresh and retry

Encrypted Storage

Optional AES-GCM 256-bit encryption for tokens at rest:

import { AuthSDK, EncryptedStorageAdapter, LocalStorageAdapter } from 'sdk-simple-auth';

const auth = new AuthSDK({
  authServiceUrl: 'http://localhost:3000',
  storage: {
    type: 'localStorage',
    encryption: {
      enabled: true,
      secret: 'your-unique-secret-key', // use a strong random value in production
    },
  },
});

// Or wrap any adapter manually:
const encrypted = new EncryptedStorageAdapter(new LocalStorageAdapter(), 'your-secret');

Multi-Tab Sync

By default, each browser tab manages its auth state independently. Enable tabSync to synchronise login/logout/token-refresh events across all tabs of the same origin via the BroadcastChannel API:

const auth = new AuthSDK({
  authServiceUrl: 'http://localhost:3000',
  tabSync: {
    enabled: true,           // disabled by default — must opt in
    channelName: 'myapp',    // optional, default: 'default'
  },
});

Note: tabSync is opt-in (enabled: false by default). Without it, logging out in one tab will not affect other open tabs.

All tabs must use the same channelName for the sync to work. This feature is browser-only — it is automatically skipped in Node.js/SSR environments.

Several tabs or windows sharing one session

Tabs of the same origin — and the windows of a desktop app (Tauri, Electron) — share the stored session. The SDK keeps that session alive across all of them:

  • One refresh at a time. Refreshes are coordinated with the Web Locks API. The instance that gets the lock calls the refresh endpoint; the rest find the new tokens in storage and take them without another request. This matters with refresh token rotation: two tabs sending the same refresh token used to get a 401 for one of them, which ended the session everywhere. Without Web Locks, a 401 for a refresh token another tab already rotated is still recognised and does not end the session.
  • Expired access token on startup. If the refresh token is still valid (the app was closed or the machine slept), the session is renewed instead of cleared.
  • Network errors do not end the session. Only a refresh the server rejects (401/403, invalid or expired token) logs out. If the network is down when the token expires — e.g. right after waking up, while Wi-Fi reconnects — the session is kept and the next request renews it.
  • Waking up. The refresh and expiration timers fire together after a long sleep; the expiration now waits for the refresh in progress instead of logging out.

Secondary windows

For auxiliary windows of a desktop app, mark the instance as secondary:

const isAuxiliaryWindow = new URLSearchParams(location.search).has('windowId');

const auth = new AuthSDK({
  authServiceUrl: 'http://localhost:3000',
  tabSync: { enabled: true, channelName: 'myapp' },
  instanceRole: isAuxiliaryWindow ? 'secondary' : 'primary',
});

A secondary instance:

  • never refreshes tokens — the primary does, and broadcasts them;
  • never clears the shared storage on its own (expired token on startup, a 401, a remote logout…), which used to log out the main window too;
  • when its token is missing or expired, asks a primary for the session over tabSync and waits up to tabSync.sessionRequestTimeout (default 5000 ms);
  • still logs out everywhere on an explicit logout().

Exports

| Export | Description | |--------|-------------| | AuthSDK | Main class | | useAuth | React hook | | createQuickNodeAuth(url) | Factory for Node.js/Express | | createQuickSanctumAuth(url) | Factory for Laravel Sanctum | | quickAnalyzeAndCreate(response, url) | Auto-detect backend from response | | AxiosInterceptorManager | Axios integration | | EncryptedStorageAdapter | AES-GCM encrypted storage | | LocalStorageAdapter | localStorage adapter | | IndexedDBAdapter | IndexedDB adapter | | SessionValidator | Session validation | | TokenExtractor | Token parsing utilities | | AuthDebugger | Debug utilities (token inspection, response analysis) | | BACKEND_PRESETS | Config presets for each backend type |


Compatibility

| Environment | Support | |-------------|---------| | Browsers | Chrome, Firefox, Safari, Edge (ES2018+) | | Node.js | 18+ (or provide httpClient for older versions) | | React | 16.8+ (hooks) | | TypeScript | 4.5+ | | Bundlers | Webpack, Vite, Rollup, Parcel | | Formats | ESM, CJS, UMD |


License

MIT — see LICENSE


Developed by Olivio Subelza