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

w3home-utils

v1.3.2

Published

W3Home Utilities - Authorization, Activity Logging, Auth Utilities

Downloads

65

Readme

w3home-utils

W3Home Utilities - Authorization, Activity Logging, and Authentication utilities for HomePay services.

Installation

npm install w3home-utils

Usage

const {
  // Authentication
  getIndetifiers,
  getIndetifiersCognito,
  verifyW3JWT,
  getUser,
  getUserType,
  decodeIdToken,
  clearUserCache,

  // W3 User Mapping
  resolveW3UserToHomepayUser,
  clearMappingCache,

  // Redis/JWKS Cache (advanced)
  getRedisClient,
  getCachedJWKS,

  // Authorization
  authorize,
  withAuthorization,
  authorizeBuyer,
  authorizeBackofficeProject,
  ROLES,
  UserType,

  // Activity Logging
  logActivity,
  logPostActivity,
  withActivityLogging,

  // Common
  corsHeaders
} = require('w3home-utils');

Authentication

Dual-Auth Support (W3 Platform + Cognito)

w3home-utils v1.1.0 supports dual authentication via the AUTH_MODE environment variable:

  • cognito (default): Legacy Cognito JWT decode
  • w3: W3 Platform JWT validation with user mapping
  • dual: Try W3 first, fall back to Cognito on failure

Get User Identifiers from Request Headers

const { getIndetifiers } = require('w3home-utils');

const handler = async (event) => {
  // Returns: { userId: string|null, w3Sub: string|null, authType?: 'w3'|'cognito' }
  const { userId, w3Sub, authType } = await getIndetifiers(event.headers);
  if (!userId) {
    return { statusCode: 401, body: JSON.stringify({ error: 'Unauthorized' }) };
  }
  // ... continue with userId
};

Return shape:

  • userId: Homepay user ID (always present for authenticated users)
  • w3Sub: W3 platform user ID (present only for W3-authenticated users)
  • authType: 'w3' or 'cognito' (indicates which auth backend was used)

Get User Details

const { getUser, getUserType } = require('w3home-utils');

const handler = async (event) => {
  const { userId } = await getIndetifiers(event.headers);
  const user = await getUser(userId);
  const userType = getUserType(user); // 'BUYER' | 'BACKOFFICE_USER' | 'BACKOFFICE_ADMIN'
  // ...
};

Authorization

Using withAuthorization Wrapper

const { withAuthorization, getUser } = require('w3home-utils');

const myHandler = async (event, context) => {
  // event.authContext contains authorization result
  const { authorized, role, permissions } = event.authContext;
  // ...
};

module.exports.handler = withAuthorization(myHandler, {
  resource: 'projects',
  getResourceId: (event) => event.pathParameters?.projectId,
  getUser: (userId) => getUser(userId)
});

Manual Authorization Check

const { authorize, getUserType } = require('w3home-utils');

const handler = async (event) => {
  const { userId } = await getIndetifiers(event.headers);
  const user = await getUser(userId);
  
  const authResult = await authorize({
    userId,
    userType: getUserType(user),
    resource: 'projects',
    action: 'READ',
    resourceId: event.pathParameters?.projectId,
    user
  });
  
  if (!authResult.authorized) {
    return { statusCode: 403, body: JSON.stringify({ error: 'Forbidden' }) };
  }
  // ...
};

Activity Logging

Using withActivityLogging Wrapper

const { withActivityLogging, getIndetifiers } = require('w3home-utils');

const myHandler = async (event, context) => {
  // Your handler logic
  return { statusCode: 200, body: JSON.stringify({ success: true }) };
};

module.exports.handler = withActivityLogging(myHandler, {
  resource: 'payments',
  extractUserId: async (event) => {
    const { userId } = await getIndetifiers(event.headers);
    return userId;
  }
});

Manual Activity Logging

const { logPostActivity } = require('w3home-utils');

const handler = async (event, context) => {
  const { userId } = await getIndetifiers(event.headers);
  
  // ... perform action ...
  
  logPostActivity({
    event,
    userId,
    action: 'CREATE',
    resource: 'payments',
    statusCode: 200,
    context
  });
};

Roles & Permissions

const { ROLES, UserType, hasPermission } = require('w3home-utils');

// Check if user has permission
const canRead = await hasPermission(userId, 'projects', 'READ');

// Get role definitions
console.log(ROLES.BACKOFFICE_ADMIN);
// { id: 'BACKOFFICE_ADMIN', permissions: [...] }

// User types
console.log(UserType.BUYER);         // 'BUYER'
console.log(UserType.BACKOFFICE_USER); // 'BACKOFFICE_USER'

Environment Variables

Core Configuration

| Variable | Default | Description | |----------|---------|-------------| | USERS_TABLE | w3HomeUsers | DynamoDB table for users | | ROLES_TABLE | w3home-roles | DynamoDB table for roles | | CONFIG_TABLE | w3home-config | DynamoDB table for config | | STAGE | dev | Environment stage |

Authentication Mode (v1.1.0+)

| Variable | Values | Description | |----------|--------|-------------| | AUTH_MODE | cognito (default), w3, dual | Authentication backend selector |

Auth modes:

  • cognito: Legacy Cognito JWT decode (backward compatible)
  • w3: W3 Platform JWT validation + user mapping lookup
  • dual: Try W3 first, fall back to Cognito on failure (recommended for migration)

W3 Platform Configuration (required when AUTH_MODE=w3 or dual)

| Variable | Required | Default | Description | |----------|----------|---------|-------------| | W3_JWKS_URL | Yes | - | W3 platform JWKS endpoint URL | | W3_ISSUER | Yes | - | W3 platform issuer (iss claim) | | W3_USER_MAPPING_TABLE | No | w3UserMapping | DynamoDB table for w3UserId → homepayUserId mapping |

Redis Configuration (required for W3 JWKS caching)

| Variable | Required | Default | Description | |----------|----------|---------|-------------| | REDIS_HOST | Yes | - | Redis host for JWKS cache | | REDIS_PORT | No | 6379 | Redis port | | REDIS_PASSWORD | Yes* | - | Redis password (*required for production) | | REDIS_TLS | No | false | Enable TLS for Redis connection |

JWKS cache TTL: 10 minutes (reduces load on W3 platform JWKS endpoint)

Peer Dependencies

This package requires aws-sdk as a peer dependency. In Lambda, this is already available. For local development:

npm install aws-sdk --save-dev

Migration Guide

Migrating to W3 Platform Authentication (v1.1.0)

Step 1: Update w3home-utils

npm update w3home-utils

Step 2: Enable dual-auth mode

Add to your Lambda environment variables:

AUTH_MODE=dual
W3_JWKS_URL=https://api.w3mcp.ai/.well-known/jwks.json
W3_ISSUER=https://api.w3mcp.ai
W3_USER_MAPPING_TABLE=w3UserMapping  # Optional, defaults to this
REDIS_HOST=your-redis-host
REDIS_PORT=6379
REDIS_PASSWORD=your-redis-password
REDIS_TLS=true  # For production

Step 3: No code changes needed!

getIndetifiers() now returns { userId, w3Sub, authType }. The userId field works exactly as before.

Optional: Use w3Sub for enhanced audit trails:

const { userId, w3Sub, authType } = await getIndetifiers(event.headers);
logActivity({
  event,
  userId,
  w3Sub,  // Now captured in activity logs
  action: 'READ',
  resource: 'projects',
  statusCode: 200
});

Rollback: Set AUTH_MODE=cognito to instantly revert to Cognito-only auth.

Cutover: Once all users migrated to W3 platform, set AUTH_MODE=w3 for W3-only validation (no Cognito fallback).

License

UNLICENSED - HomePay Internal Use Only