UNPKG

@noony-serverless/core

Version:

A Middy base framework compatible with Firebase and GCP Cloud Functions with TypeScript

393 lines 14.4 kB
"use strict"; /** * Guard System Configuration * * Comprehensive configuration system for the high-performance guard system. * Provides type-safe configuration for different deployment environments with * configurable performance strategies and security policies. * * Key Features: * - Permission resolution strategy configuration (pre-expansion vs on-demand) * - Cache adapter injection for different environments * - Performance profiles for development, staging, and production * - Security policies with conservative cache invalidation * - Bounded complexity limits for patterns and expressions * * @author Noony Framework Team * @version 1.0.0 */ Object.defineProperty(exports, "__esModule", { value: true }); exports.GuardConfiguration = exports.MonitoringLevel = exports.CacheInvalidationStrategy = exports.PermissionResolutionStrategy = void 0; /** * Permission resolution strategies for wildcard permissions. * Determines how wildcard patterns are processed for optimal performance. * * @example * Pre-expansion strategy (production recommended): * ```typescript * const productionConfig = { * permissionResolutionStrategy: PermissionResolutionStrategy.PRE_EXPANSION, * // Expands "admin.*" to ["admin.users", "admin.reports", "admin.settings"] * // at user context load time for O(1) runtime checks * }; * ``` * * @example * On-demand strategy (memory efficient): * ```typescript * const memoryEfficientConfig = { * permissionResolutionStrategy: PermissionResolutionStrategy.ON_DEMAND, * // Matches "admin.*" pattern against user permissions at runtime * // Lower memory usage but requires pattern matching overhead * }; * ``` * * PRE_EXPANSION: Expand wildcards at user context load time * - Pros: Faster runtime permission checks (O(1) set lookups) * - Cons: Higher memory usage, requires permission registry * * ON_DEMAND: Match wildcards at permission check time * - Pros: Lower memory usage, supports dynamic permissions * - Cons: Pattern matching overhead per request */ var PermissionResolutionStrategy; (function (PermissionResolutionStrategy) { PermissionResolutionStrategy["PRE_EXPANSION"] = "pre-expansion"; PermissionResolutionStrategy["ON_DEMAND"] = "on-demand"; })(PermissionResolutionStrategy || (exports.PermissionResolutionStrategy = PermissionResolutionStrategy = {})); /** * Cache invalidation strategies for security */ var CacheInvalidationStrategy; (function (CacheInvalidationStrategy) { CacheInvalidationStrategy["FLUSH_ALL"] = "flush-all"; CacheInvalidationStrategy["USER_SPECIFIC"] = "user-specific"; })(CacheInvalidationStrategy || (exports.CacheInvalidationStrategy = CacheInvalidationStrategy = {})); /** * Performance monitoring levels */ var MonitoringLevel; (function (MonitoringLevel) { MonitoringLevel["NONE"] = "none"; MonitoringLevel["BASIC"] = "basic"; MonitoringLevel["DETAILED"] = "detailed"; MonitoringLevel["VERBOSE"] = "verbose"; })(MonitoringLevel || (exports.MonitoringLevel = MonitoringLevel = {})); /** * GuardConfiguration class implementation. * Immutable configuration object for the Noony guard system with factory methods * for creating configurations from environment profiles or predefined templates. * * @example * Create from environment profile: * ```typescript * import { GuardConfiguration } from '@noony/core'; * * const config = GuardConfiguration.fromEnvironmentProfile({ * environment: 'production', * cacheType: 'redis', * security: { ... }, * cache: { ... }, * monitoring: { ... } * }); * ``` * * @example * Use predefined configurations: * ```typescript * // Development configuration * const devConfig = GuardConfiguration.development(); * * // Production configuration * const prodConfig = GuardConfiguration.production(); * * // Testing configuration * const testConfig = GuardConfiguration.testing(); * ``` * * @example * Manual configuration: * ```typescript * const customConfig = new GuardConfiguration( * { permissionResolutionStrategy: PermissionResolutionStrategy.PRE_EXPANSION }, * { maxEntries: 10000, defaultTtlMs: 300000 }, * { enablePerformanceTracking: true, logLevel: 'info' } * ); * ``` */ class GuardConfiguration { /** * Security configuration settings. * Contains permission resolution strategies and security limits. */ security; /** * Cache configuration settings. * Contains cache size limits and TTL values. */ cache; /** * Monitoring configuration settings. * Contains logging and metrics collection settings. */ monitoring; /** * Creates a new GuardConfiguration instance. * * @param security - Security configuration settings * @param cache - Cache configuration settings * @param monitoring - Monitoring configuration settings * * @example * ```typescript * const config = new GuardConfiguration( * { * permissionResolutionStrategy: PermissionResolutionStrategy.PRE_EXPANSION, * conservativeCacheInvalidation: true, * maxExpressionComplexity: 100 * }, * { * maxEntries: 10000, * defaultTtlMs: 300000, * userContextTtlMs: 600000, * authTokenTtlMs: 900000 * }, * { * enablePerformanceTracking: true, * enableDetailedLogging: false, * logLevel: 'info', * metricsCollectionInterval: 60000 * } * ); * ``` */ constructor(security, cache, monitoring) { this.security = security; this.cache = cache; this.monitoring = monitoring; } /** * Create GuardConfiguration from environment profile. * Factory method that constructs a configuration from a complete environment profile. * * @param profile - Complete environment profile with all configuration sections * @returns New GuardConfiguration instance * * @example * Create from production profile: * ```typescript * const productionProfile: GuardEnvironmentProfile = { * environment: 'production', * cacheType: 'redis', * security: { * permissionResolutionStrategy: PermissionResolutionStrategy.PRE_EXPANSION, * conservativeCacheInvalidation: true, * maxExpressionComplexity: 100 * }, * cache: { * maxEntries: 50000, * defaultTtlMs: 600000, * userContextTtlMs: 1800000, * authTokenTtlMs: 3600000 * }, * monitoring: { * enablePerformanceTracking: true, * enableDetailedLogging: false, * logLevel: 'error', * metricsCollectionInterval: 60000 * } * }; * * const config = GuardConfiguration.fromEnvironmentProfile(productionProfile); * ``` */ static fromEnvironmentProfile(profile) { return new GuardConfiguration(profile.security, profile.cache, profile.monitoring); } /** * Create default development configuration. * Pre-configured settings optimized for development environments with fast refresh * and detailed logging for debugging. * * @returns GuardConfiguration optimized for development * * @example * ```typescript * const devConfig = GuardConfiguration.development(); * * // Configuration includes: * // - On-demand permission resolution (lower memory, dynamic) * // - Conservative cache invalidation disabled (faster refresh) * // - Lower complexity limits for faster feedback * // - Shorter TTL values for rapid development cycles * // - Detailed logging and debug level * // - Frequent metrics collection (30 seconds) * ``` */ static development() { return new GuardConfiguration({ permissionResolutionStrategy: PermissionResolutionStrategy.ON_DEMAND, conservativeCacheInvalidation: false, maxExpressionComplexity: 50, maxPatternDepth: 3, maxNestingDepth: 2, }, { maxEntries: 500, defaultTtlMs: 5 * 60 * 1000, // 5 minutes userContextTtlMs: 2 * 60 * 1000, // 2 minutes authTokenTtlMs: 2 * 60 * 1000, // 2 minutes }, { enablePerformanceTracking: true, enableDetailedLogging: true, logLevel: 'debug', metricsCollectionInterval: 30000, // 30 seconds }); } /** * Create default production configuration. * Pre-configured settings optimized for production environments with high performance, * security, and stability. * * @returns GuardConfiguration optimized for production * * @example * ```typescript * const prodConfig = GuardConfiguration.production(); * * // Configuration includes: * // - Pre-expansion permission resolution (high performance) * // - Conservative cache invalidation enabled (high security) * // - Higher complexity limits for production workloads * // - Longer TTL values for better performance * // - Performance tracking enabled, detailed logging disabled * // - Standard metrics collection (1 minute intervals) * ``` */ static production() { return new GuardConfiguration({ permissionResolutionStrategy: PermissionResolutionStrategy.PRE_EXPANSION, conservativeCacheInvalidation: true, maxExpressionComplexity: 100, maxPatternDepth: 3, maxNestingDepth: 2, }, { maxEntries: 2000, defaultTtlMs: 15 * 60 * 1000, // 15 minutes userContextTtlMs: 10 * 60 * 1000, // 10 minutes authTokenTtlMs: 5 * 60 * 1000, // 5 minutes }, { enablePerformanceTracking: true, enableDetailedLogging: false, logLevel: 'info', metricsCollectionInterval: 60000, // 1 minute }); } /** * Validate configuration settings. * Ensures all configuration values are within acceptable bounds and constraints * to prevent security vulnerabilities and performance issues. * * @throws Error if any configuration value is invalid * * @example * ```typescript * const config = new GuardConfiguration(securityConfig, cacheConfig, monitoringConfig); * * try { * config.validate(); * console.log('Configuration is valid'); * } catch (error) { * console.error('Invalid configuration:', error.message); * // Handle configuration error * } * ``` * * @example * Validation constraints: * ```typescript * // These will throw validation errors: * // maxPatternDepth must be 2 or 3 (prevents deep recursion) * // maxNestingDepth must be 2 (prevents complex expressions) * // maxExpressionComplexity must be positive * // defaultTtlMs must be at least 1000ms (1 second) * ``` */ /** * Check if caching is enabled via environment variable. * * Caching is disabled by default for security-first approach. * Only enabled when NOONY_GUARD_CACHE_ENABLE is explicitly set to 'true'. * * @returns true if caching should be enabled, false otherwise * * @example * ```typescript * // Caching disabled (default) * process.env.NOONY_GUARD_CACHE_ENABLE = undefined; * console.log(GuardConfiguration.isCachingEnabled()); // false * * // Caching enabled * process.env.NOONY_GUARD_CACHE_ENABLE = 'true'; * console.log(GuardConfiguration.isCachingEnabled()); // true * * // Caching disabled (any other value) * process.env.NOONY_GUARD_CACHE_ENABLE = 'false'; * console.log(GuardConfiguration.isCachingEnabled()); // false * ``` */ static isCachingEnabled() { return process.env.NOONY_GUARD_CACHE_ENABLE === 'true'; } /** * Get effective cache type considering environment variable override. * * Environment variable takes precedence for security: * - If NOONY_GUARD_CACHE_ENABLE is not 'true', returns 'none' * - Otherwise returns the specified cacheType * * @param cacheType - Configured cache type * @returns Effective cache type after environment variable consideration * * @example * ```typescript * // Environment variable not set - caching disabled * process.env.NOONY_GUARD_CACHE_ENABLE = undefined; * console.log(GuardConfiguration.getEffectiveCacheType('memory')); // 'none' * console.log(GuardConfiguration.getEffectiveCacheType('redis')); // 'none' * console.log(GuardConfiguration.getEffectiveCacheType('none')); // 'none' * * // Environment variable enabled - respect cacheType * process.env.NOONY_GUARD_CACHE_ENABLE = 'true'; * console.log(GuardConfiguration.getEffectiveCacheType('memory')); // 'memory' * console.log(GuardConfiguration.getEffectiveCacheType('redis')); // 'redis' * console.log(GuardConfiguration.getEffectiveCacheType('none')); // 'none' * ``` */ static getEffectiveCacheType(cacheType) { // If caching is disabled by environment variable, always return 'none' if (!GuardConfiguration.isCachingEnabled()) { return 'none'; } // Otherwise return the specified cache type return cacheType; } validate() { if (this.security.maxPatternDepth !== undefined && (this.security.maxPatternDepth < 2 || this.security.maxPatternDepth > 3)) { throw new Error('maxPatternDepth must be 2 or 3'); } if (this.security.maxNestingDepth !== undefined && this.security.maxNestingDepth !== 2) { throw new Error('maxNestingDepth must be 2'); } if (this.security.maxExpressionComplexity !== undefined && this.security.maxExpressionComplexity < 1) { throw new Error('maxExpressionComplexity must be positive'); } if (this.cache.defaultTtlMs < 1000) { throw new Error('defaultTtlMs must be at least 1 second'); } } } exports.GuardConfiguration = GuardConfiguration; //# sourceMappingURL=GuardConfiguration.js.map