@noony-serverless/core
Version:
A Middy base framework compatible with Firebase and GCP Cloud Functions with TypeScript
205 lines • 7.32 kB
JavaScript
;
/**
* Cache Abstraction Layer for High-Performance Guard System
*
* This module provides a pluggable caching interface that allows different
* cache implementations to be injected based on deployment requirements:
* - MemoryCacheAdapter: LRU cache for single-instance deployments
* - RedisCacheAdapter: Distributed cache for multi-instance deployments
* - HybridCacheAdapter: L1 (memory) + L2 (Redis) for maximum performance
* - NoopCacheAdapter: Disabled caching for testing scenarios
*
* The abstraction enables sub-millisecond authentication lookups while
* maintaining flexibility for different environments.
*
* @author Noony Framework Team
* @version 1.0.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.CacheKeyBuilder = void 0;
/**
* Cache key utilities for consistent key generation.
* Provides standardized key generation methods for different types of cached data
* in the guard system, ensuring consistent naming and avoiding key collisions.
*
* @example
* Basic key generation:
* ```typescript
* // Generate cache keys for different data types
* const userKey = CacheKeyBuilder.userContext('user123');
* // Returns: "noony:guard:user:user123"
*
* const tokenKey = CacheKeyBuilder.authToken('jwt-token-here');
* // Returns: "noony:guard:auth:jwt-toke...ken-here"
*
* const permKey = CacheKeyBuilder.userPermission('user123', 'admin.users.read');
* // Returns: "noony:guard:perm:user123:admin.users.read"
* ```
*
* @example
* Pattern-based cache keys:
* ```typescript
* // Cache wildcard resolution results
* const patterns = ['admin.*', 'user.read'];
* const userPerms = ['admin.users', 'admin.reports', 'user.read'];
* const wildcardKey = CacheKeyBuilder.wildcardPattern(patterns, userPerms);
*
* // Cache expression evaluation results
* const expr = '(admin.users OR admin.reports) AND user.active';
* const exprKey = CacheKeyBuilder.expressionResult(expr, userPerms);
* ```
*
* @example
* Custom key generation:
* ```typescript
* // Generate application-specific keys
* const customKey = CacheKeyBuilder.custom('feature', 'value1', 'value2');
* // Returns: "noony:guard:feature:value1:value2"
* ```
*/
class CacheKeyBuilder {
static PREFIX = 'noony:guard';
/**
* Generate a cache key for user context.
* Creates a standardized key for caching user authentication and role data.
*
* @param userId - Unique identifier for the user
* @returns Cache key string for user context
*
* @example
* ```typescript
* const key = CacheKeyBuilder.userContext('user123');
* // Returns: "noony:guard:user:user123"
*
* await cache.set(key, {
* userId: 'user123',
* roles: ['admin', 'user'],
* permissions: ['read', 'write'],
* lastLogin: new Date()
* });
* ```
*/
static userContext(userId) {
return `${this.PREFIX}:user:${userId}`;
}
/**
* Generate a cache key for authentication token.
* Creates a secure key by using partial token hash to avoid storing full tokens.
*
* @param token - Authentication token (JWT, API key, etc.)
* @returns Cache key string for auth token
*
* @example
* ```typescript
* const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';
* const key = CacheKeyBuilder.authToken(token);
* // Returns: "noony:guard:auth:eyJhbGci...dCI6IkpXVCJ9"
*
* await cache.set(key, {
* valid: true,
* userId: 'user123',
* expires: new Date(Date.now() + 3600000)
* });
* ```
*/
static authToken(token) {
const tokenHash = token.substring(0, 8) + '...' + token.substring(token.length - 8);
return `${this.PREFIX}:auth:${tokenHash}`;
}
/**
* Generate a cache key for wildcard permission resolution.
* Creates a key for caching the results of wildcard pattern matching
* against user permissions.
*
* @param patterns - Array of wildcard patterns to match
* @param userPermissions - Array of user's actual permissions
* @returns Cache key string for wildcard resolution
*
* @example
* ```typescript
* const patterns = ['admin.*', 'user.read'];
* const userPerms = ['admin.users', 'admin.reports', 'user.read'];
* const key = CacheKeyBuilder.wildcardPattern(patterns, userPerms);
* // Returns: "noony:guard:wildcard:hash1:hash2"
*
* // Cache the expansion result
* await cache.set(key, {
* matched: ['admin.users', 'admin.reports', 'user.read'],
* expandedPatterns: {
* 'admin.*': ['admin.users', 'admin.reports'],
* 'user.read': ['user.read']
* }
* });
* ```
*/
static wildcardPattern(patterns, userPermissions) {
const patternHash = this.hashArray(patterns);
const permissionHash = this.hashArray(userPermissions);
return `${this.PREFIX}:wildcard:${patternHash}:${permissionHash}`;
}
/**
* Generate a cache key for expression permission resolution.
* Creates a key for caching the results of boolean expression evaluation
* against user permissions.
*
* @param expression - Boolean expression object to evaluate
* @param userPermissions - Array of user's actual permissions
* @returns Cache key string for expression evaluation
*
* @example
* ```typescript
* const expression = {
* type: 'AND',
* left: { type: 'permission', value: 'admin.users' },
* right: { type: 'permission', value: 'admin.reports' }
* };
* const userPerms = ['admin.users', 'admin.reports', 'user.read'];
* const key = CacheKeyBuilder.expressionResult(expression, userPerms);
* // Returns: "noony:guard:expression:exprHash:permHash"
*
* // Cache the evaluation result
* await cache.set(key, {
* result: true,
* evaluatedAt: new Date(),
* usedPermissions: ['admin.users', 'admin.reports']
* });
* ```
*/
static expressionResult(expression, userPermissions) {
const expressionHash = this.hashObject(expression);
const permissionHash = this.hashArray(userPermissions);
return `${this.PREFIX}:expression:${expressionHash}:${permissionHash}`;
}
/**
* Generate a cache key for permission registry data
*/
static permissionRegistry(category) {
return category
? `${this.PREFIX}:registry:${category}`
: `${this.PREFIX}:registry:all`;
}
/**
* Simple hash function for arrays (not cryptographically secure)
*/
static hashArray(arr) {
return arr
.sort()
.join(':')
.split('')
.reduce((hash, char) => {
const charCode = char.charCodeAt(0);
hash = (hash << 5) - hash + charCode;
return hash & hash; // Convert to 32-bit integer
}, 0)
.toString(36);
}
/**
* Simple hash function for objects (not cryptographically secure)
*/
static hashObject(obj) {
const str = JSON.stringify(obj, Object.keys(obj).sort());
return this.hashArray([str]);
}
}
exports.CacheKeyBuilder = CacheKeyBuilder;
//# sourceMappingURL=CacheAdapter.js.map