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

@carisls/sso-core

v1.2.0

Published

A core component used by other components

Readme

@carisls/sso-core

A core SSO (Single Sign-On) component library for JWT token validation, user mapping, and authorization. This package provides essential utilities for handling OIDC/OAuth2 authentication flows, token validation, and Express.js middleware integration.

Note: This package is typically not installed directly. It is automatically installed as a dependency of other SSO packages:

  • @carisls/sso-standard
  • @carisls/sso-resource-api

Features

  • 🔐 JWT token validation with JWKS support
  • 🔑 Public key fetching and caching
  • 👤 User token mapping and transformation
  • 🛡️ Express.js authorization middleware
  • 🔒 Encryption/decryption utilities
  • 🌐 Multi-issuer support
  • 📦 Supports both ESM and CommonJS

Installation

This package is usually installed automatically as a dependency. If you need to install it directly:

npm install @carisls/sso-core

Usage

ESM (ECMAScript Modules)

import {
  authorize,
  certFetcherModule,
  encryptorModule,
  HttpError,
  issuerSelectorModule,
  postForm,
  tokenDecoderModule,
  tokenValidatorModule,
  userMapper
} from '@carisls/sso-core';

CommonJS

const {
  authorize,
  certFetcherModule,
  encryptorModule,
  HttpError,
  issuerSelectorModule,
  postForm,
  tokenDecoderModule,
  tokenValidatorModule,
  userMapper
} = require('@carisls/sso-core');

API Reference

authorize(role, exceptions, redirectToLogin)

Express.js middleware for authorization filtering based on user roles.

Parameters:

  • role (string | string[] | undefined): Role(s) to filter by. If undefined, only checks for authenticated user.
  • exceptions (string[] | undefined): Array of URL paths to skip authorization.
  • redirectToLogin (boolean, default: false): If true, redirects to login page instead of returning 401.

Returns: Express middleware function (req, res, next) => void

Example:

import express from 'express';
import { authorize } from '@carisls/sso-core';

const app = express();

// Require any authenticated user
app.use(authorize());

// Require specific role
app.use('/admin', authorize('admin'));

// Require one of multiple roles
app.use('/dashboard', authorize(['admin', 'user']));

// With exceptions and redirect
app.use(authorize('user', ['/public', '/health'], true));

certFetcherModule(jwksUri, publicKeyCache)

Creates a function to fetch and cache public keys from a JWKS (JSON Web Key Set) endpoint.

Parameters:

  • jwksUri (string): URL to the JWKS endpoint (e.g., https://example.com/.well-known/jwks.json)
  • publicKeyCache (number, default: 300): Cache expiration time in seconds.

Returns: Async function (kid) => Promise<string> that returns the PEM-formatted public key for the given key ID.

Example:

import { certFetcherModule } from '@carisls/sso-core';

const getCert = certFetcherModule('https://auth.example.com/.well-known/jwks.json', 600);

// Get public key for a specific key ID
const publicKey = await getCert('key-id-123');

encryptorModule(password, passwordSalt, iterationCount)

Creates an encryption/decryption utility.

Parameters:

  • password (string): Encryption password.
  • passwordSalt (string, default: 'C5mp4Hl$X9wby#s5'): Salt for password derivation.
  • iterationCount (number, default: 123123): Number of iterations for key derivation.

Returns: Object with encrypt and decrypt methods.

Example:

import { encryptorModule } from '@carisls/sso-core';

const { encrypt, decrypt } = encryptorModule('my-secret-password');

const encrypted = encrypt('sensitive data');
const decrypted = decrypt(encrypted);

issuerSelectorModule(providers, cache)

Creates a validator that supports multiple JWT issuers/providers.

Parameters:

  • providers (Array<{ ssoUrl?: string, iss?: string, publicKey?: string }>): Array of provider configurations.
    • ssoUrl: OpenID Connect configuration URL (e.g., https://auth.example.com)
    • iss: Issuer identifier (used as fallback if ssoUrl fails)
    • publicKey: Optional static public key (PEM format) if not using JWKS
  • cache (number): Public key cache duration in seconds.

Returns: Promise resolving to an object with:

  • validator(tokenEnc, nonce, decodeOnly): Async function to validate tokens
  • providers: Map of configured providers

Example:

import { issuerSelectorModule } from '@carisls/sso-core';

const { validator } = await issuerSelectorModule([
  { ssoUrl: 'https://auth1.example.com', iss: 'https://auth1.example.com' },
  { ssoUrl: 'https://auth2.example.com', iss: 'https://auth2.example.com' },
  { publicKey: '-----BEGIN PUBLIC KEY-----\n...', iss: 'static-issuer' }
], 600);

// Validate token
try {
  const result = await validator(encryptedToken, nonce);
  console.log('Token valid:', result.token);
} catch (error) {
  console.error('Token validation failed:', error.message);
}

// Decode only (no validation)
const { token } = await validator(encryptedToken, null, true);

postForm(url, data)

Sends a POST request with form-urlencoded data.

Parameters:

  • url (string): Target URL.
  • data (object): Data object to be encoded as form data.

Returns: Promise resolving to the response data.

Example:

import { postForm } from '@carisls/sso-core';

const response = await postForm('https://auth.example.com/token', {
  grant_type: 'authorization_code',
  code: 'auth-code-123',
  client_id: 'my-client',
  client_secret: 'my-secret'
});

tokenDecoderModule

Utility object for decoding JWT tokens without validation.

Methods:

  • header(encToken): Decodes and returns the JWT header.
  • data(encToken): Decodes and returns the JWT payload.

Example:

import { tokenDecoderModule } from '@carisls/sso-core';

const token = 'eyJhbGciOiJSUzI1NiIs...';

const header = tokenDecoderModule.header(token);
const payload = tokenDecoderModule.data(token);

console.log('Algorithm:', header.alg);
console.log('User ID:', payload.sub);

tokenValidatorModule(jwksUri, publicKeyCache, publicKey)

Creates a token validator function.

Parameters:

  • jwksUri (string | null): JWKS endpoint URL. If null, uses publicKey instead.
  • publicKeyCache (number): Cache duration in seconds (ignored if publicKey is provided).
  • publicKey (string | undefined): Optional static public key in PEM format.

Returns: Async function (tokenEnc, nonce) => Promise<{ token, publicKey }>

Example:

import { tokenValidatorModule } from '@carisls/sso-core';

// Using JWKS
const validateWithJWKS = tokenValidatorModule(
  'https://auth.example.com/.well-known/jwks.json',
  600
);

// Using static public key
const validateWithKey = tokenValidatorModule(
  null,
  0,
  '-----BEGIN PUBLIC KEY-----\n...'
);

const result = await validateWithJWKS(encryptedToken, 'nonce-value');
console.log('Validated token:', result.token);
console.log('Public key used:', result.publicKey);

userMapper(token, idToken)

Maps a JWT token to a standardized user object.

Parameters:

  • token (object): Decoded JWT access token.
  • idToken (object | undefined): Optional decoded ID token.

Returns: User object with the following structure:

{
  iss: string;              // Issuer
  id: string;               // User ID (from 'sub')
  sid?: string;             // Session ID
  sa: boolean;              // Service account flag (true if no session)
  azp?: string;             // Authorized party
  name?: {                  // Name object (only if session exists)
    full: string;
    familyName: string;
    givenName: string;
  };
  email?: string;           // Email (only if session exists)
  roles: string[];          // User roles
}

Example:

import { userMapper } from '@carisls/sso-core';

const decodedToken = {
  iss: 'https://auth.example.com',
  sub: 'user-123',
  sid: 'session-456',
  email: '[email protected]',
  given_name: 'John',
  family_name: 'Doe',
  roles: ['user', 'admin']
};

const user = userMapper(decodedToken);
// {
//   iss: 'https://auth.example.com',
//   id: 'user-123',
//   sid: 'session-456',
//   sa: false,
//   name: {
//     full: 'John Doe',
//     familyName: 'Doe',
//     givenName: 'John'
//   },
//   email: '[email protected]',
//   roles: ['user', 'admin']
// }

Complete Example

import express from 'express';
import {
  issuerSelectorModule,
  userMapper,
  authorize
} from '@carisls/sso-core';

const app = express();

// Configure SSO providers
const { validator } = await issuerSelectorModule([
  { ssoUrl: 'https://auth.example.com', iss: 'https://auth.example.com' }
], 600);

// Express middleware to validate tokens
app.use(async (req, res, next) => {
  try {
    const token = req.headers.authorization?.replace('Bearer ', '');
    if (!token) {
      return next({ status: 401, message: 'No token provided' });
    }

    const { token: decodedToken } = await validator(token);
    req.user = userMapper(decodedToken);
    next();
  } catch (error) {
    next({ status: 401, message: error.message });
  }
});

// Protected route with role-based authorization
app.get('/admin', authorize('admin'), (req, res) => {
  res.json({ message: 'Admin access granted', user: req.user });
});

app.listen(3000);

License

MIT

Author

Mihovil Strujic [email protected]