@lock-dev/core
Version:
Core security framework for lock.dev
219 lines (212 loc) • 8.38 kB
TypeScript
/**
* Security context that's passed through the module chain
*/
interface SecurityContext<TRequest = any, TResponse = any> {
/** Original request object (framework-specific) */
request: TRequest;
/** Original response object (framework-specific) */
response: TResponse;
/** Authenticated user object (if available) */
user?: any;
/** Whether the request has been denied by any security module */
denied: boolean;
/** Reason for denial (if denied) */
deniedReason?: string;
/** Security events that occurred during processing */
events: SecurityEvent[];
/** Timestamp when processing started */
startTime: number;
/** Timestamp when processing ended */
endTime?: number;
/** Custom data shared between modules */
data: Map<string, any>;
/** Security configuration */
config: Record<string, any>;
}
/**
* Severity level for security events
*/
type SecurityEventSeverity = 'low' | 'medium' | 'high' | 'critical';
/**
* Security event types
*/
declare enum SecurityEventType {
/** Authentication successful */
AUTH_SUCCESS = "auth_success",
/** Authentication failed */
AUTH_FAILURE = "auth_failure",
/** Rate limit exceeded */
RATE_LIMIT_EXCEEDED = "rate_limit_exceeded",
/** Input validation failed */
VALIDATION_FAILURE = "validation_failure",
/** CSRF token invalid/missing */
CSRF_VIOLATION = "csrf_violation",
/** Access denied due to insufficient permissions */
AUTHORIZATION_FAILURE = "authorization_failure",
/** Access denied due to geographic restrictions */
GEO_BLOCKED = "geo_blocked",
/** Internal error occurred */
INTERNAL_ERROR = "internal_error"
}
/**
* Security event details
*/
interface SecurityEvent {
/** Type of event */
type: SecurityEventType;
/** Timestamp when event occurred */
timestamp: number;
/** Human-readable message */
message: string;
/** Additional event data */
data?: any;
/** Event severity */
severity: SecurityEventSeverity;
/** Module that generated the event */
moduleName: string;
}
/**
* Result of a security check
*/
interface SecurityCheckResult {
/** Whether the check passed */
passed: boolean;
/** Event details if the check failed */
event?: SecurityEvent;
/** Updated security context */
context: SecurityContext;
}
/**
* Base security module interface
*/
interface SecurityModule {
/** Unique module name */
name: string;
/**
* Run security check
* @param context Current security context
* @returns Result of the security check
*/
check(context: SecurityContext): Promise<SecurityCheckResult>;
/**
* Handle failure if the check fails
* @param context Current security context
* @param event Security event that caused the failure
*/
handleFailure?(context: SecurityContext, event: SecurityEvent): Promise<void>;
}
/**
* Core security manager responsible for running security modules.
*/
declare class SecurityManager {
private modules;
/**
* Registers a security module.
*
* @param {SecurityModule} module - The security module to register.
* @returns {this} The SecurityManager instance.
*/
registerModule(module: SecurityModule): this;
/**
* Runs all registered security checks using the provided context.
*
* @param {SecurityContext} context - The initial security context.
* @returns {Promise<boolean>} A promise that resolves to true if all checks pass; otherwise, false.
*/
runSecurityChecks(context: SecurityContext): Promise<boolean>;
}
/**
* Definition for creating a security module.
*
* @template TConfig - The type of the configuration object.
*/
interface ModuleDefinition<TConfig = any> {
/**
* Module name.
*/
name: string;
/**
* Module check function.
*
* @param {SecurityContext} context - The security context.
* @param {TConfig} config - The module configuration.
* @returns {Promise<{ passed: boolean; reason?: string; data?: any; severity?: 'low' | 'medium' | 'high' | 'critical' }>}
* A promise that resolves to an object indicating whether the check passed, along with optional reason, data, and severity.
*/
check: (context: SecurityContext, config: TConfig) => Promise<{
passed: boolean;
reason?: string;
data?: any;
severity?: 'low' | 'medium' | 'high' | 'critical';
}>;
/**
* Optional failure handler.
*
* @param {SecurityContext} context - The security context.
* @param {string} reason - The reason for failure.
* @param {*} [data] - Optional additional data.
* @returns {Promise<void>} A promise that resolves when the failure is handled.
*/
handleFailure?: (context: SecurityContext, reason: string, data?: any) => Promise<void>;
/**
* Default configuration for the module.
*/
defaultConfig?: Partial<TConfig>;
}
/**
* Creates a security module factory.
*
* @param definition Module definition.
* @returns Factory function that creates configured security modules.
*/
declare function createModule<TConfig = any>(definition: ModuleDefinition<TConfig>): (config?: Partial<TConfig>) => SecurityModule;
/**
* Creates a security pipeline by composing multiple security modules.
* The returned module performs a sequential check using the provided modules.
* If any module fails its check, the pipeline stops and returns that failure result.
* Additionally, it delegates failure handling to the specific module that failed.
*
* @param {...SecurityModule[]} modules - An array of security modules to be composed.
* @returns {SecurityModule} A composed security module that integrates the provided modules.
*/
declare function composeModules(...modules: SecurityModule[]): SecurityModule;
/**
* Creates a new security context.
*
* @template TRequest The type of the request.
* @template TResponse The type of the response.
* @param {TRequest} request - The request object.
* @param {TResponse} response - The response object.
* @param {Record<string, any>} [config={}] - Optional configuration object.
* @returns {SecurityContext<TRequest, TResponse>} A new security context object.
*/
declare function createContext<TRequest, TResponse>(request: TRequest, response: TResponse, config?: Record<string, any>): SecurityContext<TRequest, TResponse>;
/**
* Register a security module for use with secureRoute
* @param name Module name to use in configuration
* @param factory Module factory function
*/
declare function registerModule(name: string, factory: (config: any) => SecurityModule): (config: any) => SecurityModule;
/**
* Secure route handler with declarative configuration.
*
* Wraps an original route handler (Next.js, Express, etc.) with security checks using configured modules.
* If no modules are configured, the original handler is returned. Otherwise, the security checks are performed
* using the composed security modules, and access is allowed only if all checks pass.
*
* @param {Function} handler - The original route handler.
* @param {Record<string, any>} [options={}] - Security configuration options.
* @returns {Function} The secured route handler.
*/
declare function secureRoute(handler: Function, options?: Record<string, any>): Function;
/**
* Secures a route handler or middleware by applying security modules.
* The returned function accepts security modules and returns an asynchronous middleware.
* If the security checks pass, it calls the original handler (Next.js style) or next middleware (Express style).
* Otherwise, it sends a 403 response with detailed metadata about the security event.
*
* @param {Function} [handler] - Optional original route handler.
* @returns {(...modules: SecurityModule[]) => Function} A function that takes security modules and returns a secured middleware.
*/
declare function secure(handler?: Function): (...modules: SecurityModule[]) => (req: any, res: any, next?: Function) => Promise<any>;
export { type ModuleDefinition, type SecurityCheckResult, type SecurityContext, type SecurityEvent, type SecurityEventSeverity, SecurityEventType, SecurityManager, type SecurityModule, composeModules, createContext, createModule, registerModule, secure, secureRoute };