w3home-utils
v1.3.2
Published
W3Home Utilities - Authorization, Activity Logging, Auth Utilities
Downloads
65
Maintainers
Readme
w3home-utils
W3Home Utilities - Authorization, Activity Logging, and Authentication utilities for HomePay services.
Installation
npm install w3home-utilsUsage
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 decodew3: W3 Platform JWT validation with user mappingdual: 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 lookupdual: 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-devMigration Guide
Migrating to W3 Platform Authentication (v1.1.0)
Step 1: Update w3home-utils
npm update w3home-utilsStep 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 productionStep 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
