content-security-toolkit 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +9 -0
- package/README.md +171 -0
- package/dist/config/default-extensions-config.json +103 -0
- package/dist/core/ContentProtector.d.ts +63 -0
- package/dist/core/ContentProtector.js +279 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +2 -0
- package/dist/core/mediator/ContentProtectionMediator.d.ts +86 -0
- package/dist/core/mediator/ContentProtectionMediator.js +238 -0
- package/dist/core/mediator/eventDataTypes.d.ts +205 -0
- package/dist/core/mediator/eventDataTypes.js +23 -0
- package/dist/core/mediator/handlers/abstractEventHandler.d.ts +67 -0
- package/dist/core/mediator/handlers/abstractEventHandler.js +106 -0
- package/dist/core/mediator/handlers/baseEventHandler.d.ts +65 -0
- package/dist/core/mediator/handlers/baseEventHandler.js +99 -0
- package/dist/core/mediator/handlers/devToolsEventHandler.d.ts +9 -0
- package/dist/core/mediator/handlers/devToolsEventHandler.js +95 -0
- package/dist/core/mediator/handlers/eventHandlerRegistry.d.ts +9 -0
- package/dist/core/mediator/handlers/eventHandlerRegistry.js +34 -0
- package/dist/core/mediator/handlers/extensionEventHandlers.d.ts +40 -0
- package/dist/core/mediator/handlers/extensionEventHandlers.js +140 -0
- package/dist/core/mediator/handlers/iFrameEventHandlers.d.ts +27 -0
- package/dist/core/mediator/handlers/iFrameEventHandlers.js +93 -0
- package/dist/core/mediator/handlers/index.d.ts +9 -0
- package/dist/core/mediator/handlers/index.js +34 -0
- package/dist/core/mediator/handlers/screenShotEventHandlers.d.ts +34 -0
- package/dist/core/mediator/handlers/screenShotEventHandlers.js +111 -0
- package/dist/core/mediator/protection-event.d.ts +94 -0
- package/dist/core/mediator/protection-event.js +43 -0
- package/dist/core/mediator/types.d.ts +105 -0
- package/dist/core/mediator/types.js +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +5 -0
- package/dist/strategies/AbstractStrategy.d.ts +152 -0
- package/dist/strategies/AbstractStrategy.js +296 -0
- package/dist/strategies/AbstractStrategy.mediator.d.ts +162 -0
- package/dist/strategies/AbstractStrategy.mediator.js +349 -0
- package/dist/strategies/ClipboardStrategy.d.ts +67 -0
- package/dist/strategies/ClipboardStrategy.js +291 -0
- package/dist/strategies/ContextMenuStrategy.d.ts +60 -0
- package/dist/strategies/ContextMenuStrategy.js +454 -0
- package/dist/strategies/DevToolsStrategy copy.d.ts +85 -0
- package/dist/strategies/DevToolsStrategy copy.js +362 -0
- package/dist/strategies/DevToolsStrategy-detectorManager.d.ts +70 -0
- package/dist/strategies/DevToolsStrategy-detectorManager.js +309 -0
- package/dist/strategies/DevToolsStrategy-simple.d.ts +75 -0
- package/dist/strategies/DevToolsStrategy-simple.js +366 -0
- package/dist/strategies/DevToolsStrategy.d.ts +55 -0
- package/dist/strategies/DevToolsStrategy.js +314 -0
- package/dist/strategies/ExtensionStrategy.d.ts +66 -0
- package/dist/strategies/ExtensionStrategy.js +486 -0
- package/dist/strategies/IFrameStrategy.d.ts +49 -0
- package/dist/strategies/IFrameStrategy.js +255 -0
- package/dist/strategies/KeyboardStrategy.d.ts +35 -0
- package/dist/strategies/KeyboardStrategy.js +130 -0
- package/dist/strategies/PrintStrategy.d.ts +47 -0
- package/dist/strategies/PrintStrategy.js +201 -0
- package/dist/strategies/ScreenshotStrategy.d.ts +90 -0
- package/dist/strategies/ScreenshotStrategy.js +488 -0
- package/dist/strategies/SelectionStrategy.d.ts +49 -0
- package/dist/strategies/SelectionStrategy.js +216 -0
- package/dist/strategies/StrategyRegistry.d.ts +133 -0
- package/dist/strategies/StrategyRegistry.js +379 -0
- package/dist/strategies/WatermarkStrategy.d.ts +47 -0
- package/dist/strategies/WatermarkStrategy.js +273 -0
- package/dist/strategies/index.d.ts +9 -0
- package/dist/strategies/index.js +10 -0
- package/dist/types/index.d.ts +271 -0
- package/dist/types/index.js +16 -0
- package/dist/utils/DOMObserver.d.ts +68 -0
- package/dist/utils/DOMObserver.js +134 -0
- package/dist/utils/base/LoggableComponent.d.ts +62 -0
- package/dist/utils/base/LoggableComponent.js +95 -0
- package/dist/utils/debuggerDetector/debuggerDetectionWorker.d.ts +6 -0
- package/dist/utils/debuggerDetector/debuggerDetectionWorker.js +24 -0
- package/dist/utils/debuggerDetector/debuggerDetector.d.ts +55 -0
- package/dist/utils/debuggerDetector/debuggerDetector.js +158 -0
- package/dist/utils/debuggerDetector/firefoxDetector.d.ts +8 -0
- package/dist/utils/debuggerDetector/firefoxDetector.js +64 -0
- package/dist/utils/detection.d.ts +29 -0
- package/dist/utils/detection.js +267 -0
- package/dist/utils/detectors/AbstractDevToolsDetector.d.ts +105 -0
- package/dist/utils/detectors/AbstractDevToolsDetector.js +136 -0
- package/dist/utils/detectors/dateToStringDetector.d.ts +43 -0
- package/dist/utils/detectors/dateToStringDetector.js +96 -0
- package/dist/utils/detectors/debugLibDetector.d.ts +64 -0
- package/dist/utils/detectors/debugLibDetector.js +195 -0
- package/dist/utils/detectors/debuggerDetectionWorker.d.ts +6 -0
- package/dist/utils/detectors/debuggerDetectionWorker.js +24 -0
- package/dist/utils/detectors/debuggerDetector.d.ts +51 -0
- package/dist/utils/detectors/debuggerDetector.js +211 -0
- package/dist/utils/detectors/defineGetterDetector.d.ts +48 -0
- package/dist/utils/detectors/defineGetterDetector.js +150 -0
- package/dist/utils/detectors/detectorInterface.d.ts +36 -0
- package/dist/utils/detectors/detectorInterface.js +1 -0
- package/dist/utils/detectors/devToolsDetectorManager.d.ts +88 -0
- package/dist/utils/detectors/devToolsDetectorManager.js +246 -0
- package/dist/utils/detectors/firefoxDetector.d.ts +8 -0
- package/dist/utils/detectors/firefoxDetector.js +64 -0
- package/dist/utils/detectors/funcToStringDetector.d.ts +43 -0
- package/dist/utils/detectors/funcToStringDetector.js +90 -0
- package/dist/utils/detectors/regToStringDetector.d.ts +43 -0
- package/dist/utils/detectors/regToStringDetector.js +129 -0
- package/dist/utils/detectors/sizeDetector.d.ts +54 -0
- package/dist/utils/detectors/sizeDetector.js +134 -0
- package/dist/utils/detectors/timingDetector.d.ts +55 -0
- package/dist/utils/detectors/timingDetector.js +143 -0
- package/dist/utils/dom.d.ts +20 -0
- package/dist/utils/dom.js +83 -0
- package/dist/utils/environment.d.ts +29 -0
- package/dist/utils/environment.js +267 -0
- package/dist/utils/eventManager.d.ts +167 -0
- package/dist/utils/eventManager.js +556 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/intervalManager.d.ts +96 -0
- package/dist/utils/intervalManager.js +229 -0
- package/dist/utils/keyboardShortcutManager/keyboardShortcutManager.d.ts +41 -0
- package/dist/utils/keyboardShortcutManager/keyboardShortcutManager.js +135 -0
- package/dist/utils/keyboardShortcutManager/keyboardShortcuts.d.ts +18 -0
- package/dist/utils/keyboardShortcutManager/keyboardShortcuts.js +195 -0
- package/dist/utils/logging/LogLevel.d.ts +21 -0
- package/dist/utils/logging/LogLevel.js +46 -0
- package/dist/utils/logging/LoggingConfig.d.ts +68 -0
- package/dist/utils/logging/LoggingConfig.js +64 -0
- package/dist/utils/logging/LoggingFactory.d.ts +22 -0
- package/dist/utils/logging/LoggingFactory.js +61 -0
- package/dist/utils/logging/LoggingService.d.ts +235 -0
- package/dist/utils/logging/LoggingService.js +385 -0
- package/dist/utils/logging/SimpleLoggingService.d.ts +39 -0
- package/dist/utils/logging/SimpleLoggingService.js +58 -0
- package/dist/utils/logging/advanced/LogLevel.d.ts +21 -0
- package/dist/utils/logging/advanced/LogLevel.js +46 -0
- package/dist/utils/logging/advanced/LoggingConfig.d.ts +68 -0
- package/dist/utils/logging/advanced/LoggingConfig.js +64 -0
- package/dist/utils/logging/advanced/LoggingFactory.d.ts +22 -0
- package/dist/utils/logging/advanced/LoggingFactory.js +61 -0
- package/dist/utils/logging/advanced/LoggingService.d.ts +235 -0
- package/dist/utils/logging/advanced/LoggingService.js +385 -0
- package/dist/utils/logging/simple/Loggable.d.ts +33 -0
- package/dist/utils/logging/simple/Loggable.js +1 -0
- package/dist/utils/logging/simple/LoggingDelegate.d.ts +42 -0
- package/dist/utils/logging/simple/LoggingDelegate.js +53 -0
- package/dist/utils/logging/simple/SimpleLoggingService.d.ts +39 -0
- package/dist/utils/logging/simple/SimpleLoggingService.js +58 -0
- package/dist/utils/orientation.d.ts +15 -0
- package/dist/utils/orientation.js +32 -0
- package/dist/utils/protectedContentManager-simple.d.ts +86 -0
- package/dist/utils/protectedContentManager-simple.js +180 -0
- package/dist/utils/protectedContentManager.d.ts +162 -0
- package/dist/utils/protectedContentManager.js +427 -0
- package/dist/utils/screenshotDetector.d.ts +72 -0
- package/dist/utils/screenshotDetector.js +179 -0
- package/dist/utils/securityOverlayManager-observer-pause.d.ts +283 -0
- package/dist/utils/securityOverlayManager-observer-pause.js +878 -0
- package/dist/utils/securityOverlayManager-simple.d.ts +197 -0
- package/dist/utils/securityOverlayManager-simple.js +552 -0
- package/dist/utils/securityOverlayManager.d.ts +260 -0
- package/dist/utils/securityOverlayManager.js +774 -0
- package/dist/utils/timeoutManager.d.ts +55 -0
- package/dist/utils/timeoutManager.js +121 -0
- package/package.json +54 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import type { ProtectionStrategy } from "../types";
|
|
2
|
+
import type { MediatorAware, ProtectionMediator } from "../core/mediator/types";
|
|
3
|
+
import { SimpleLoggingService } from "../utils/logging/simple/SimpleLoggingService";
|
|
4
|
+
/**
|
|
5
|
+
* Error types for protection strategies
|
|
6
|
+
*/
|
|
7
|
+
export declare enum StrategyErrorType {
|
|
8
|
+
INITIALIZATION = "initialization",
|
|
9
|
+
APPLICATION = "application",
|
|
10
|
+
REMOVAL = "removal",
|
|
11
|
+
EVENT_HANDLING = "event_handling",
|
|
12
|
+
OPTION_UPDATE = "option_update",
|
|
13
|
+
UNKNOWN = "unknown"
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Custom error class for protection strategies
|
|
17
|
+
*/
|
|
18
|
+
export declare class StrategyError extends Error {
|
|
19
|
+
readonly strategyName: string;
|
|
20
|
+
readonly errorType: StrategyErrorType;
|
|
21
|
+
readonly originalError?: (Error | unknown) | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Create a new StrategyError
|
|
24
|
+
* @param strategyName Name of the strategy where the error occurred
|
|
25
|
+
* @param errorType Type of error that occurred
|
|
26
|
+
* @param message Error message
|
|
27
|
+
* @param originalError Original error that was caught (if any)
|
|
28
|
+
*/
|
|
29
|
+
constructor(strategyName: string, errorType: StrategyErrorType, message: string, originalError?: (Error | unknown) | undefined);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Abstract base class for protection strategies
|
|
33
|
+
* Implements common functionality to reduce duplication
|
|
34
|
+
*/
|
|
35
|
+
export declare abstract class AbstractStrategy implements ProtectionStrategy, MediatorAware {
|
|
36
|
+
readonly STRATEGY_NAME: string;
|
|
37
|
+
readonly COMPONENT_NAME: string;
|
|
38
|
+
protected debugMode: boolean;
|
|
39
|
+
protected mediator: ProtectionMediator | null;
|
|
40
|
+
protected isAppliedFlag: boolean;
|
|
41
|
+
protected logger: SimpleLoggingService;
|
|
42
|
+
protected eventIds: string[];
|
|
43
|
+
/**
|
|
44
|
+
* Create a new strategy
|
|
45
|
+
* @param strategyName Unique name for the strategy
|
|
46
|
+
* @param debugMode Enable debug mode for troubleshooting
|
|
47
|
+
*/
|
|
48
|
+
constructor(strategyName: string, debugMode?: boolean);
|
|
49
|
+
/**
|
|
50
|
+
* Set the mediator
|
|
51
|
+
* to communicate with the other components
|
|
52
|
+
*/
|
|
53
|
+
setMediator(mediator: ProtectionMediator): void;
|
|
54
|
+
/**
|
|
55
|
+
* Apply the protection strategy
|
|
56
|
+
* Must be implemented by subclasses
|
|
57
|
+
*/
|
|
58
|
+
abstract apply(): void;
|
|
59
|
+
/**
|
|
60
|
+
* Remove the protection strategy
|
|
61
|
+
* Can be overridden by subclasses for custom cleanup
|
|
62
|
+
*/
|
|
63
|
+
remove(): void;
|
|
64
|
+
/**
|
|
65
|
+
* Check if the strategy is currently applied
|
|
66
|
+
*/
|
|
67
|
+
isApplied(): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Update strategy options
|
|
70
|
+
* Should be implemented by subclasses that support options
|
|
71
|
+
*/
|
|
72
|
+
updateOptions(options: Record<string, unknown>): void;
|
|
73
|
+
/**
|
|
74
|
+
* Get the debug mode status
|
|
75
|
+
*/
|
|
76
|
+
isDebugEnabled(): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Set debug mode
|
|
79
|
+
*/
|
|
80
|
+
setDebugMode(enabled: boolean): void;
|
|
81
|
+
/**
|
|
82
|
+
* Handle an error that occurred in the strategy
|
|
83
|
+
* @param errorType Type of error
|
|
84
|
+
* @param message Error message
|
|
85
|
+
* @param originalError Original error that was caught
|
|
86
|
+
*/
|
|
87
|
+
protected handleError(errorType: StrategyErrorType, message: string, originalError?: unknown): void;
|
|
88
|
+
/**
|
|
89
|
+
* Log a debug message if debug mode is enabled
|
|
90
|
+
* @param message Message to log
|
|
91
|
+
* @param args Additional arguments to log
|
|
92
|
+
*/
|
|
93
|
+
protected log(message: string, ...args: unknown[]): void;
|
|
94
|
+
/**
|
|
95
|
+
* Log a warning message
|
|
96
|
+
* @param message Warning message
|
|
97
|
+
* @param args Additional arguments to log
|
|
98
|
+
*/
|
|
99
|
+
protected warn(message: string, ...args: unknown[]): void;
|
|
100
|
+
/**
|
|
101
|
+
* Log an error message
|
|
102
|
+
* @param message Error message
|
|
103
|
+
* @param args Additional arguments to log
|
|
104
|
+
*/
|
|
105
|
+
protected error(message: string, ...args: unknown[]): void;
|
|
106
|
+
/**
|
|
107
|
+
* Execute a function with error handling
|
|
108
|
+
* @param operation Name of the operation for error reporting
|
|
109
|
+
* @param errorType Type of error for categorization
|
|
110
|
+
* @param fn Function to execute
|
|
111
|
+
* @returns The result of the function or undefined if an error occurred
|
|
112
|
+
*/
|
|
113
|
+
protected safeExecute<T>(operation: string, errorType: StrategyErrorType, fn: () => T): T | undefined;
|
|
114
|
+
/**
|
|
115
|
+
* Execute an async function with error handling
|
|
116
|
+
* @param operation Name of the operation for error reporting
|
|
117
|
+
* @param errorType Type of error for categorization
|
|
118
|
+
* @param fn Async function to execute
|
|
119
|
+
* @returns Promise resolving to the result of the function or undefined if an error occurred
|
|
120
|
+
*/
|
|
121
|
+
protected safeExecuteAsync<T>(operation: string, errorType: StrategyErrorType, fn: () => Promise<T>): Promise<T | undefined>;
|
|
122
|
+
/**
|
|
123
|
+
* Register an event with the EventManager
|
|
124
|
+
* @param target The target element, document, or window
|
|
125
|
+
* @param eventType The type of event (e.g., "click", "keydown")
|
|
126
|
+
* @param handler The event handler function
|
|
127
|
+
* @param options Additional options for the event listener
|
|
128
|
+
* @returns The ID of the registered event
|
|
129
|
+
*/
|
|
130
|
+
protected registerEvent(target: EventTarget | null, eventType: string, handler: EventListener, options?: AddEventListenerOptions & {
|
|
131
|
+
priority?: number;
|
|
132
|
+
id?: string;
|
|
133
|
+
}): string;
|
|
134
|
+
/**
|
|
135
|
+
* Remove all event listeners for this strategy
|
|
136
|
+
* @returns The number of events removed
|
|
137
|
+
*/
|
|
138
|
+
protected removeEventsByOwner(): number;
|
|
139
|
+
/**
|
|
140
|
+
* Remove all event listeners for a specific target
|
|
141
|
+
* @param target The target to remove events from
|
|
142
|
+
* @returns The number of events removed
|
|
143
|
+
*/
|
|
144
|
+
protected removeAllEventsForTarget(target: EventTarget | null): number;
|
|
145
|
+
/**
|
|
146
|
+
* Remove event listeners by CSS selector
|
|
147
|
+
* @param selector CSS selector to match elements
|
|
148
|
+
* @param eventType Type of event to remove
|
|
149
|
+
* @returns The number of events removed
|
|
150
|
+
*/
|
|
151
|
+
protected removeEventsBySelector(selector: string, eventType: string): number;
|
|
152
|
+
}
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import { eventManager } from "../utils/eventManager";
|
|
2
|
+
import { isBrowser } from "../utils/environment";
|
|
3
|
+
import { SimpleLoggingService } from "../utils/logging/simple/SimpleLoggingService";
|
|
4
|
+
/**
|
|
5
|
+
* Error types for protection strategies
|
|
6
|
+
*/
|
|
7
|
+
export var StrategyErrorType;
|
|
8
|
+
(function (StrategyErrorType) {
|
|
9
|
+
StrategyErrorType["INITIALIZATION"] = "initialization";
|
|
10
|
+
StrategyErrorType["APPLICATION"] = "application";
|
|
11
|
+
StrategyErrorType["REMOVAL"] = "removal";
|
|
12
|
+
StrategyErrorType["EVENT_HANDLING"] = "event_handling";
|
|
13
|
+
StrategyErrorType["OPTION_UPDATE"] = "option_update";
|
|
14
|
+
StrategyErrorType["UNKNOWN"] = "unknown";
|
|
15
|
+
})(StrategyErrorType || (StrategyErrorType = {}));
|
|
16
|
+
/**
|
|
17
|
+
* Custom error class for protection strategies
|
|
18
|
+
*/
|
|
19
|
+
export class StrategyError extends Error {
|
|
20
|
+
/**
|
|
21
|
+
* Create a new StrategyError
|
|
22
|
+
* @param strategyName Name of the strategy where the error occurred
|
|
23
|
+
* @param errorType Type of error that occurred
|
|
24
|
+
* @param message Error message
|
|
25
|
+
* @param originalError Original error that was caught (if any)
|
|
26
|
+
*/
|
|
27
|
+
constructor(strategyName, errorType, message, originalError) {
|
|
28
|
+
super(`[${strategyName}] ${message}${originalError instanceof Error ? `: ${originalError.message}` : ""}`);
|
|
29
|
+
this.strategyName = strategyName;
|
|
30
|
+
this.errorType = errorType;
|
|
31
|
+
this.originalError = originalError;
|
|
32
|
+
this.name = "StrategyError";
|
|
33
|
+
// Maintain the stack trace
|
|
34
|
+
if (Error.captureStackTrace) {
|
|
35
|
+
Error.captureStackTrace(this, StrategyError);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Abstract base class for protection strategies
|
|
41
|
+
* Implements common functionality to reduce duplication
|
|
42
|
+
*/
|
|
43
|
+
export class AbstractStrategy {
|
|
44
|
+
/**
|
|
45
|
+
* Create a new strategy
|
|
46
|
+
* @param strategyName Unique name for the strategy
|
|
47
|
+
* @param debugMode Enable debug mode for troubleshooting
|
|
48
|
+
*/
|
|
49
|
+
constructor(strategyName, debugMode = false) {
|
|
50
|
+
this.mediator = null;
|
|
51
|
+
this.isAppliedFlag = false;
|
|
52
|
+
this.eventIds = [];
|
|
53
|
+
this.STRATEGY_NAME = strategyName;
|
|
54
|
+
this.COMPONENT_NAME = strategyName;
|
|
55
|
+
this.debugMode = debugMode;
|
|
56
|
+
this.logger = new SimpleLoggingService(strategyName, debugMode);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Set the mediator
|
|
60
|
+
* to communicate with the other components
|
|
61
|
+
*/
|
|
62
|
+
setMediator(mediator) {
|
|
63
|
+
this.mediator = mediator;
|
|
64
|
+
this.logger.log("Mediator set");
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Remove the protection strategy
|
|
68
|
+
* Can be overridden by subclasses for custom cleanup
|
|
69
|
+
*/
|
|
70
|
+
remove() {
|
|
71
|
+
try {
|
|
72
|
+
if (!this.isAppliedFlag) {
|
|
73
|
+
this.logger.log("Protection not applied");
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (isBrowser()) {
|
|
77
|
+
// Remove all event listeners using EventManager
|
|
78
|
+
const removedCount = this.removeEventsByOwner();
|
|
79
|
+
// Clear the event IDs array
|
|
80
|
+
this.eventIds = [];
|
|
81
|
+
this.isAppliedFlag = false;
|
|
82
|
+
this.logger.log(`Protection removed (${removedCount} events)`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
this.handleError(StrategyErrorType.REMOVAL, "Failed to remove protection", error);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Check if the strategy is currently applied
|
|
91
|
+
*/
|
|
92
|
+
isApplied() {
|
|
93
|
+
return this.isAppliedFlag;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Update strategy options
|
|
97
|
+
* Should be implemented by subclasses that support options
|
|
98
|
+
*/
|
|
99
|
+
updateOptions(options) {
|
|
100
|
+
try {
|
|
101
|
+
// Default implementation just logs that the method is not implemented
|
|
102
|
+
this.logger.log("Method updateOptions not implemented", options);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
this.handleError(StrategyErrorType.OPTION_UPDATE, "Failed to update options", error);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get the debug mode status
|
|
110
|
+
*/
|
|
111
|
+
isDebugEnabled() {
|
|
112
|
+
return this.debugMode;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Set debug mode
|
|
116
|
+
*/
|
|
117
|
+
setDebugMode(enabled) {
|
|
118
|
+
this.debugMode = enabled;
|
|
119
|
+
this.logger.setDebugMode(enabled);
|
|
120
|
+
this.logger.log(`Debug mode ${enabled ? "enabled" : "disabled"}`);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Handle an error that occurred in the strategy
|
|
124
|
+
* @param errorType Type of error
|
|
125
|
+
* @param message Error message
|
|
126
|
+
* @param originalError Original error that was caught
|
|
127
|
+
*/
|
|
128
|
+
handleError(errorType, message, originalError) {
|
|
129
|
+
const error = new StrategyError(this.STRATEGY_NAME, errorType, message, originalError);
|
|
130
|
+
if (this.debugMode) {
|
|
131
|
+
console.error(error);
|
|
132
|
+
if (error.originalError instanceof Error && error.originalError.stack) {
|
|
133
|
+
console.error("Original stack:", error.originalError.stack);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
console.error(error.message);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Log a debug message if debug mode is enabled
|
|
142
|
+
* @param message Message to log
|
|
143
|
+
* @param args Additional arguments to log
|
|
144
|
+
*/
|
|
145
|
+
log(message, ...args) {
|
|
146
|
+
this.logger.log(message, ...args);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Log a warning message
|
|
150
|
+
* @param message Warning message
|
|
151
|
+
* @param args Additional arguments to log
|
|
152
|
+
*/
|
|
153
|
+
warn(message, ...args) {
|
|
154
|
+
this.logger.warn(message, ...args);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Log an error message
|
|
158
|
+
* @param message Error message
|
|
159
|
+
* @param args Additional arguments to log
|
|
160
|
+
*/
|
|
161
|
+
error(message, ...args) {
|
|
162
|
+
this.logger.error(message, ...args);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Execute a function with error handling
|
|
166
|
+
* @param operation Name of the operation for error reporting
|
|
167
|
+
* @param errorType Type of error for categorization
|
|
168
|
+
* @param fn Function to execute
|
|
169
|
+
* @returns The result of the function or undefined if an error occurred
|
|
170
|
+
*/
|
|
171
|
+
safeExecute(operation, errorType, fn) {
|
|
172
|
+
try {
|
|
173
|
+
return fn();
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
this.handleError(errorType, `Error during ${operation}`, error);
|
|
177
|
+
return undefined;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Execute an async function with error handling
|
|
182
|
+
* @param operation Name of the operation for error reporting
|
|
183
|
+
* @param errorType Type of error for categorization
|
|
184
|
+
* @param fn Async function to execute
|
|
185
|
+
* @returns Promise resolving to the result of the function or undefined if an error occurred
|
|
186
|
+
*/
|
|
187
|
+
async safeExecuteAsync(operation, errorType, fn) {
|
|
188
|
+
try {
|
|
189
|
+
return await fn();
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
this.handleError(errorType, `Error during ${operation}`, error);
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Register an event with the EventManager
|
|
198
|
+
* @param target The target element, document, or window
|
|
199
|
+
* @param eventType The type of event (e.g., "click", "keydown")
|
|
200
|
+
* @param handler The event handler function
|
|
201
|
+
* @param options Additional options for the event listener
|
|
202
|
+
* @returns The ID of the registered event
|
|
203
|
+
*/
|
|
204
|
+
registerEvent(target, eventType, handler, options) {
|
|
205
|
+
if (!target || !isBrowser())
|
|
206
|
+
return "";
|
|
207
|
+
// Defensive check: ensure the provided target supports addEventListener
|
|
208
|
+
// This prevents runtime TypeError when non-DOM objects (Vue refs, selectors, etc.) are passed
|
|
209
|
+
// and provides a clearer StrategyError for easier debugging.
|
|
210
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
211
|
+
if (typeof target.addEventListener !== "function") {
|
|
212
|
+
this.handleError(StrategyErrorType.EVENT_HANDLING, `Invalid event target for ${eventType} - target does not implement addEventListener`, new Error("target.addEventListener is not a function"));
|
|
213
|
+
return "";
|
|
214
|
+
}
|
|
215
|
+
try {
|
|
216
|
+
// Create a wrapped handler that includes error handling
|
|
217
|
+
const wrappedHandler = (event) => {
|
|
218
|
+
try {
|
|
219
|
+
return handler(event);
|
|
220
|
+
}
|
|
221
|
+
catch (error) {
|
|
222
|
+
this.handleError(StrategyErrorType.EVENT_HANDLING, `Error handling ${eventType} event`, error);
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
// Pass all options including priority to the eventManager
|
|
226
|
+
const eventId = eventManager.addEventListener(target, eventType, wrappedHandler, this.STRATEGY_NAME, options);
|
|
227
|
+
if (eventId) {
|
|
228
|
+
this.eventIds.push(eventId);
|
|
229
|
+
this.logger.log(`Registered ${eventType} event (ID: ${eventId})`);
|
|
230
|
+
}
|
|
231
|
+
return eventId;
|
|
232
|
+
}
|
|
233
|
+
catch (error) {
|
|
234
|
+
this.handleError(StrategyErrorType.EVENT_HANDLING, `Failed to register ${eventType} event`, error);
|
|
235
|
+
return "";
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Remove all event listeners for this strategy
|
|
240
|
+
* @returns The number of events removed
|
|
241
|
+
*/
|
|
242
|
+
removeEventsByOwner() {
|
|
243
|
+
try {
|
|
244
|
+
const removedCount = eventManager.removeEventsByOwner(this.STRATEGY_NAME);
|
|
245
|
+
if (removedCount > 0) {
|
|
246
|
+
this.logger.log(`Removed ${removedCount} events by owner ID`);
|
|
247
|
+
}
|
|
248
|
+
return removedCount;
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
this.handleError(StrategyErrorType.REMOVAL, "Failed to remove events by owner", error);
|
|
252
|
+
return 0;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Remove all event listeners for a specific target
|
|
257
|
+
* @param target The target to remove events from
|
|
258
|
+
* @returns The number of events removed
|
|
259
|
+
*/
|
|
260
|
+
removeAllEventsForTarget(target) {
|
|
261
|
+
if (!target || !isBrowser())
|
|
262
|
+
return 0;
|
|
263
|
+
try {
|
|
264
|
+
const removedCount = eventManager.removeAllEventsForTarget(target);
|
|
265
|
+
if (removedCount > 0) {
|
|
266
|
+
this.logger.log(`Removed ${removedCount} events from target`);
|
|
267
|
+
}
|
|
268
|
+
return removedCount;
|
|
269
|
+
}
|
|
270
|
+
catch (error) {
|
|
271
|
+
this.handleError(StrategyErrorType.REMOVAL, "Failed to remove events for target", error);
|
|
272
|
+
return 0;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Remove event listeners by CSS selector
|
|
277
|
+
* @param selector CSS selector to match elements
|
|
278
|
+
* @param eventType Type of event to remove
|
|
279
|
+
* @returns The number of events removed
|
|
280
|
+
*/
|
|
281
|
+
removeEventsBySelector(selector, eventType) {
|
|
282
|
+
if (!isBrowser())
|
|
283
|
+
return 0;
|
|
284
|
+
try {
|
|
285
|
+
const removedCount = eventManager.removeEventsBySelector(selector, eventType, this.STRATEGY_NAME);
|
|
286
|
+
if (removedCount > 0) {
|
|
287
|
+
this.logger.log(`Removed ${removedCount} ${eventType} events via selector "${selector}"`);
|
|
288
|
+
}
|
|
289
|
+
return removedCount;
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
this.handleError(StrategyErrorType.REMOVAL, `Failed to remove events by selector "${selector}"`, error);
|
|
293
|
+
return 0;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import type { ProtectionStrategy } from "../types";
|
|
2
|
+
import type { ProtectionMediator, ProtectionEventHandler, SubscriptionOptions } from "../core/mediator/types";
|
|
3
|
+
import { ProtectionEventType } from "../core/mediator/protection-event";
|
|
4
|
+
import type { EventDataMap } from "../core/mediator/eventDataTypes";
|
|
5
|
+
/**
|
|
6
|
+
* Error types for protection strategies
|
|
7
|
+
*/
|
|
8
|
+
export declare enum StrategyErrorType {
|
|
9
|
+
INITIALIZATION = "initialization",
|
|
10
|
+
APPLICATION = "application",
|
|
11
|
+
REMOVAL = "removal",
|
|
12
|
+
EVENT_HANDLING = "event_handling",
|
|
13
|
+
OPTION_UPDATE = "option_update",
|
|
14
|
+
UNKNOWN = "unknown"
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Custom error class for protection strategies
|
|
18
|
+
*/
|
|
19
|
+
export declare class StrategyError extends Error {
|
|
20
|
+
readonly strategyName: string;
|
|
21
|
+
readonly errorType: StrategyErrorType;
|
|
22
|
+
readonly originalError?: (Error | unknown) | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* Create a new StrategyError
|
|
25
|
+
* @param strategyName Name of the strategy where the error occurred
|
|
26
|
+
* @param errorType Type of error that occurred
|
|
27
|
+
* @param message Error message
|
|
28
|
+
* @param originalError Original error that was caught (if any)
|
|
29
|
+
*/
|
|
30
|
+
constructor(strategyName: string, errorType: StrategyErrorType, message: string, originalError?: (Error | unknown) | undefined);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Abstract base class for protection strategies
|
|
34
|
+
* Implements common functionality to reduce duplication
|
|
35
|
+
*/
|
|
36
|
+
export declare abstract class AbstractStrategy implements ProtectionStrategy {
|
|
37
|
+
protected mediator: ProtectionMediator | null;
|
|
38
|
+
protected subscriptionIds: string[];
|
|
39
|
+
readonly STRATEGY_NAME: string;
|
|
40
|
+
protected isAppliedFlag: boolean;
|
|
41
|
+
protected debugMode: boolean;
|
|
42
|
+
protected eventIds: string[];
|
|
43
|
+
/**
|
|
44
|
+
* Create a new strategy
|
|
45
|
+
* @param strategyName Unique name for the strategy
|
|
46
|
+
* @param debugMode Enable debug mode for troubleshooting
|
|
47
|
+
*/
|
|
48
|
+
constructor(strategyName: string, debugMode?: boolean);
|
|
49
|
+
/**
|
|
50
|
+
* Apply the protection strategy
|
|
51
|
+
* Must be implemented by subclasses
|
|
52
|
+
*/
|
|
53
|
+
abstract apply(): void;
|
|
54
|
+
/**
|
|
55
|
+
* Set the mediator for this strategy
|
|
56
|
+
* This connects the strategy to the event system
|
|
57
|
+
* @param mediator The protection mediator instance
|
|
58
|
+
*/
|
|
59
|
+
setMediator(mediator: ProtectionMediator): void;
|
|
60
|
+
/**
|
|
61
|
+
* Helper method for subscribing to events
|
|
62
|
+
* Tracks subscription IDs for cleanup
|
|
63
|
+
*/
|
|
64
|
+
protected subscribe(eventType: ProtectionEventType, handler: ProtectionEventHandler, options?: SubscriptionOptions): string;
|
|
65
|
+
/**
|
|
66
|
+
* Helper method for publishing events
|
|
67
|
+
*/
|
|
68
|
+
protected publishEvent<T extends ProtectionEventType>(eventType: T, data?: EventDataMap[T]): void;
|
|
69
|
+
/**
|
|
70
|
+
* Remove the protection strategy
|
|
71
|
+
* Can be overridden by subclasses for custom cleanup
|
|
72
|
+
*/
|
|
73
|
+
remove(): void;
|
|
74
|
+
/**
|
|
75
|
+
* Check if the strategy is currently applied
|
|
76
|
+
*/
|
|
77
|
+
isApplied(): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Update strategy options
|
|
80
|
+
* Should be implemented by subclasses that support options
|
|
81
|
+
*/
|
|
82
|
+
updateOptions(options: Record<string, unknown>): void;
|
|
83
|
+
/**
|
|
84
|
+
* Get the debug mode status
|
|
85
|
+
*/
|
|
86
|
+
isDebugEnabled(): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Set debug mode
|
|
89
|
+
*/
|
|
90
|
+
setDebugMode(enabled: boolean): void;
|
|
91
|
+
/**
|
|
92
|
+
* Handle an error that occurred in the strategy
|
|
93
|
+
* @param errorType Type of error
|
|
94
|
+
* @param message Error message
|
|
95
|
+
* @param originalError Original error that was caught
|
|
96
|
+
*/
|
|
97
|
+
protected handleError(errorType: StrategyErrorType, message: string, originalError?: unknown): void;
|
|
98
|
+
/**
|
|
99
|
+
* Log a debug message if debug mode is enabled
|
|
100
|
+
* @param message Message to log
|
|
101
|
+
* @param args Additional arguments to log
|
|
102
|
+
*/
|
|
103
|
+
protected log(message: string, ...args: unknown[]): void;
|
|
104
|
+
/**
|
|
105
|
+
* Log a warning message
|
|
106
|
+
* @param message Warning message
|
|
107
|
+
* @param args Additional arguments to log
|
|
108
|
+
*/
|
|
109
|
+
protected warn(message: string, ...args: unknown[]): void;
|
|
110
|
+
/**
|
|
111
|
+
* Log an error message
|
|
112
|
+
* @param message Error message
|
|
113
|
+
* @param args Additional arguments to log
|
|
114
|
+
*/
|
|
115
|
+
protected error(message: string, ...args: unknown[]): void;
|
|
116
|
+
/**
|
|
117
|
+
* Execute a function with error handling
|
|
118
|
+
* @param operation Name of the operation for error reporting
|
|
119
|
+
* @param errorType Type of error for categorization
|
|
120
|
+
* @param fn Function to execute
|
|
121
|
+
* @returns The result of the function or undefined if an error occurred
|
|
122
|
+
*/
|
|
123
|
+
protected safeExecute<T>(operation: string, errorType: StrategyErrorType, fn: () => T): T | undefined;
|
|
124
|
+
/**
|
|
125
|
+
* Execute an async function with error handling
|
|
126
|
+
* @param operation Name of the operation for error reporting
|
|
127
|
+
* @param errorType Type of error for categorization
|
|
128
|
+
* @param fn Async function to execute
|
|
129
|
+
* @returns Promise resolving to the result of the function or undefined if an error occurred
|
|
130
|
+
*/
|
|
131
|
+
protected safeExecuteAsync<T>(operation: string, errorType: StrategyErrorType, fn: () => Promise<T>): Promise<T | undefined>;
|
|
132
|
+
/**
|
|
133
|
+
* Register an event with the EventManager
|
|
134
|
+
* @param target The target element, document, or window
|
|
135
|
+
* @param eventType The type of event (e.g., "click", "keydown")
|
|
136
|
+
* @param handler The event handler function
|
|
137
|
+
* @param options Additional options for the event listener
|
|
138
|
+
* @returns The ID of the registered event
|
|
139
|
+
*/
|
|
140
|
+
protected registerEvent(target: EventTarget | null, eventType: string, handler: EventListener, options?: AddEventListenerOptions & {
|
|
141
|
+
priority?: number;
|
|
142
|
+
id?: string;
|
|
143
|
+
}): string;
|
|
144
|
+
/**
|
|
145
|
+
* Remove all event listeners for this strategy
|
|
146
|
+
* @returns The number of events removed
|
|
147
|
+
*/
|
|
148
|
+
protected removeEventsByOwner(): number;
|
|
149
|
+
/**
|
|
150
|
+
* Remove all event listeners for a specific target
|
|
151
|
+
* @param target The target to remove events from
|
|
152
|
+
* @returns The number of events removed
|
|
153
|
+
*/
|
|
154
|
+
protected removeAllEventsForTarget(target: EventTarget | null): number;
|
|
155
|
+
/**
|
|
156
|
+
* Remove event listeners by CSS selector
|
|
157
|
+
* @param selector CSS selector to match elements
|
|
158
|
+
* @param eventType Type of event to remove
|
|
159
|
+
* @returns The number of events removed
|
|
160
|
+
*/
|
|
161
|
+
protected removeEventsBySelector(selector: string, eventType: string): number;
|
|
162
|
+
}
|