content-security-toolkit 1.0.1 → 1.0.2
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/README.md +22 -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/index.d.ts +9 -0
- package/dist/core/mediator/handlers/index.js +34 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/otel.d.ts +24 -0
- package/dist/otel.js +87 -0
- package/dist/strategies/AbstractStrategy.mediator.d.ts +162 -0
- package/dist/strategies/AbstractStrategy.mediator.js +349 -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/StrategyRegistry.d.ts +133 -0
- package/dist/strategies/StrategyRegistry.js +379 -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/debuggerDetectionWorker.d.ts +6 -0
- package/dist/utils/detectors/debuggerDetectionWorker.js +24 -0
- package/dist/utils/detectors/firefoxDetector.d.ts +8 -0
- package/dist/utils/detectors/firefoxDetector.js +64 -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/protectedContentManager-simple.d.ts +86 -0
- package/dist/utils/protectedContentManager-simple.js +180 -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/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Content Security Toolkit
|
|
2
2
|
|
|
3
|
+
> ## ⚠️ Deprecated — use [`@tindalabs/shield`](https://www.npmjs.com/package/@tindalabs/shield) instead
|
|
4
|
+
>
|
|
5
|
+
> This package has been superseded by **[`@tindalabs/shield`](https://github.com/tindalabs/shield)**, which keeps the entire `ContentProtector` API and adds structured risk assessment (`assess()`), an OpenTelemetry integration (`attachShieldToSpan()`), a declarative policy engine (`assessAndProtect()`), and zero runtime dependencies.
|
|
6
|
+
>
|
|
7
|
+
> **Migrate in two lines:**
|
|
8
|
+
>
|
|
9
|
+
> ```bash
|
|
10
|
+
> npm uninstall content-security-toolkit
|
|
11
|
+
> npm install @tindalabs/shield
|
|
12
|
+
> ```
|
|
13
|
+
>
|
|
14
|
+
> ```ts
|
|
15
|
+
> // Before: import { ContentProtector } from 'content-security-toolkit';
|
|
16
|
+
> // After: import { ContentProtector } from '@tindalabs/shield';
|
|
17
|
+
> ```
|
|
18
|
+
>
|
|
19
|
+
> Every `ContentProtector` option you used here works identically in Shield. Full migration guide: [github.com/tindalabs/shield/blob/main/MIGRATION.md](https://github.com/tindalabs/shield/blob/main/MIGRATION.md). See also [DEPRECATED.md](./DEPRECATED.md).
|
|
20
|
+
>
|
|
21
|
+
> Existing installs continue to work — the package is **not** unpublished. Security fixes and new features land in Shield only.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
3
25
|
[](https://www.npmjs.com/package/content-security-toolkit) [](https://github.com/Isonimus/content-security-toolkit/actions) [](LICENSE)
|
|
4
26
|
|
|
5
27
|
A comprehensive toolkit for implementing content security measures in web applications — lightweight, modular, and TypeScript-friendly.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { ProtectionMediator } from "../../mediator/types";
|
|
2
|
+
import type { ProtectionEvent, ProtectionEventType } from "../../mediator/protection-event";
|
|
3
|
+
/**
|
|
4
|
+
* Abstract base class for all event handlers
|
|
5
|
+
*/
|
|
6
|
+
export declare abstract class BaseEventHandler {
|
|
7
|
+
protected mediator: ProtectionMediator;
|
|
8
|
+
protected readonly COMPONENT_NAME: string;
|
|
9
|
+
protected debugMode: boolean;
|
|
10
|
+
protected subscriptionIds: string[];
|
|
11
|
+
/**
|
|
12
|
+
* Create a new event handler
|
|
13
|
+
* @param mediator The protection mediator
|
|
14
|
+
* @param componentName The name of the component
|
|
15
|
+
* @param debugMode Enable debug mode for troubleshooting
|
|
16
|
+
*/
|
|
17
|
+
constructor(mediator: ProtectionMediator, componentName: string, debugMode?: boolean);
|
|
18
|
+
/**
|
|
19
|
+
* Initialize the handler and subscribe to events
|
|
20
|
+
* This method should be implemented by subclasses
|
|
21
|
+
*/
|
|
22
|
+
protected abstract initialize(): void;
|
|
23
|
+
/**
|
|
24
|
+
* Log a debug message
|
|
25
|
+
* @param message Message to log
|
|
26
|
+
* @param args Additional arguments to log
|
|
27
|
+
*/
|
|
28
|
+
protected log(message: string, ...args: unknown[]): void;
|
|
29
|
+
/**
|
|
30
|
+
* Log a warning message
|
|
31
|
+
* @param message Warning message
|
|
32
|
+
* @param args Additional arguments to log
|
|
33
|
+
*/
|
|
34
|
+
protected warn(message: string, ...args: unknown[]): void;
|
|
35
|
+
/**
|
|
36
|
+
* Log an error message
|
|
37
|
+
* @param message Error message
|
|
38
|
+
* @param args Additional arguments to log
|
|
39
|
+
*/
|
|
40
|
+
protected error(message: string, ...args: unknown[]): void;
|
|
41
|
+
/**
|
|
42
|
+
* Set debug mode
|
|
43
|
+
* @param enabled Whether debug mode should be enabled
|
|
44
|
+
*/
|
|
45
|
+
setDebugMode(enabled: boolean): void;
|
|
46
|
+
/**
|
|
47
|
+
* Subscribe to an event and track the subscription ID
|
|
48
|
+
* @param eventType The event type to subscribe to
|
|
49
|
+
* @param handler The event handler function
|
|
50
|
+
* @param options Optional subscription options
|
|
51
|
+
* @returns The subscription ID
|
|
52
|
+
*/
|
|
53
|
+
protected subscribe(eventType: ProtectionEventType, handler: (event: ProtectionEvent) => void, options?: {
|
|
54
|
+
context?: string;
|
|
55
|
+
}): string;
|
|
56
|
+
/**
|
|
57
|
+
* Unsubscribe from all events and clean up
|
|
58
|
+
*/
|
|
59
|
+
dispose(): void;
|
|
60
|
+
/**
|
|
61
|
+
* Additional cleanup to be performed on disposal
|
|
62
|
+
* This method can be overridden by subclasses
|
|
63
|
+
*/
|
|
64
|
+
protected onDispose(): void;
|
|
65
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abstract base class for all event handlers
|
|
3
|
+
*/
|
|
4
|
+
export class BaseEventHandler {
|
|
5
|
+
/**
|
|
6
|
+
* Create a new event handler
|
|
7
|
+
* @param mediator The protection mediator
|
|
8
|
+
* @param componentName The name of the component
|
|
9
|
+
* @param debugMode Enable debug mode for troubleshooting
|
|
10
|
+
*/
|
|
11
|
+
constructor(mediator, componentName, debugMode = false) {
|
|
12
|
+
this.subscriptionIds = [];
|
|
13
|
+
this.mediator = mediator;
|
|
14
|
+
this.COMPONENT_NAME = componentName;
|
|
15
|
+
this.debugMode = debugMode;
|
|
16
|
+
this.initialize();
|
|
17
|
+
if (this.debugMode) {
|
|
18
|
+
this.log("Initialized and subscribed to events");
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Log a debug message
|
|
23
|
+
* @param message Message to log
|
|
24
|
+
* @param args Additional arguments to log
|
|
25
|
+
*/
|
|
26
|
+
log(message, ...args) {
|
|
27
|
+
if (this.debugMode) {
|
|
28
|
+
console.log(`${this.COMPONENT_NAME}: ${message}`, ...args);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Log a warning message
|
|
33
|
+
* @param message Warning message
|
|
34
|
+
* @param args Additional arguments to log
|
|
35
|
+
*/
|
|
36
|
+
warn(message, ...args) {
|
|
37
|
+
if (this.debugMode) {
|
|
38
|
+
console.warn(`${this.COMPONENT_NAME}: ${message}`, ...args);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
// In non-debug mode, only log the message without args for brevity
|
|
42
|
+
console.warn(`${this.COMPONENT_NAME}: ${message}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Log an error message
|
|
47
|
+
* @param message Error message
|
|
48
|
+
* @param args Additional arguments to log
|
|
49
|
+
*/
|
|
50
|
+
error(message, ...args) {
|
|
51
|
+
console.error(`${this.COMPONENT_NAME}: ${message}`, ...args);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Set debug mode
|
|
55
|
+
* @param enabled Whether debug mode should be enabled
|
|
56
|
+
*/
|
|
57
|
+
setDebugMode(enabled) {
|
|
58
|
+
this.debugMode = enabled;
|
|
59
|
+
if (this.debugMode) {
|
|
60
|
+
this.log(`Debug mode ${enabled ? "enabled" : "disabled"}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Subscribe to an event and track the subscription ID
|
|
65
|
+
* @param eventType The event type to subscribe to
|
|
66
|
+
* @param handler The event handler function
|
|
67
|
+
* @param options Optional subscription options
|
|
68
|
+
* @returns The subscription ID
|
|
69
|
+
*/
|
|
70
|
+
subscribe(eventType, handler, options) {
|
|
71
|
+
const subId = this.mediator.subscribe(eventType, handler, { ...options, context: options?.context || this.COMPONENT_NAME });
|
|
72
|
+
this.subscriptionIds.push(subId);
|
|
73
|
+
if (this.debugMode) {
|
|
74
|
+
this.log(`Subscribed to ${eventType} with ID ${subId}`);
|
|
75
|
+
}
|
|
76
|
+
return subId;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Unsubscribe from all events and clean up
|
|
80
|
+
*/
|
|
81
|
+
dispose() {
|
|
82
|
+
if (this.debugMode) {
|
|
83
|
+
this.log(`Disposing handler, unsubscribing from ${this.subscriptionIds.length} events`);
|
|
84
|
+
}
|
|
85
|
+
// Unsubscribe from all events
|
|
86
|
+
for (const id of this.subscriptionIds) {
|
|
87
|
+
this.mediator.unsubscribe(id);
|
|
88
|
+
}
|
|
89
|
+
this.subscriptionIds = [];
|
|
90
|
+
this.onDispose();
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Additional cleanup to be performed on disposal
|
|
94
|
+
* This method can be overridden by subclasses
|
|
95
|
+
*/
|
|
96
|
+
onDispose() {
|
|
97
|
+
// Default implementation does nothing
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ProtectionMediator } from "../types";
|
|
2
|
+
export declare class HandlerRegistry {
|
|
3
|
+
private handlers;
|
|
4
|
+
private mediator;
|
|
5
|
+
private debugMode;
|
|
6
|
+
constructor(mediator: ProtectionMediator, debugMode?: boolean);
|
|
7
|
+
private initializeHandlers;
|
|
8
|
+
setDebugMode(enabled: boolean): void;
|
|
9
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { DevToolsEventHandler } from "./devToolsEventHandler";
|
|
2
|
+
import { BrowserExtensionEventHandler } from "./extensionEventHandlers";
|
|
3
|
+
import { FrameEmbeddingEventHandler } from "./iFrameEventHandlers";
|
|
4
|
+
import { ScreenshotEventHandler } from "./screenShotEventHandlers";
|
|
5
|
+
export class HandlerRegistry {
|
|
6
|
+
constructor(mediator, debugMode = false) {
|
|
7
|
+
this.handlers = {};
|
|
8
|
+
this.mediator = mediator;
|
|
9
|
+
this.debugMode = debugMode;
|
|
10
|
+
this.initializeHandlers();
|
|
11
|
+
}
|
|
12
|
+
initializeHandlers() {
|
|
13
|
+
// Initialize all handlers
|
|
14
|
+
this.handlers.devTools = new DevToolsEventHandler(this.mediator, this.debugMode);
|
|
15
|
+
this.handlers.extension = new BrowserExtensionEventHandler(this.mediator, this.debugMode);
|
|
16
|
+
this.handlers.screenshot = new ScreenshotEventHandler(this.mediator, this.debugMode);
|
|
17
|
+
this.handlers.iFrame = new FrameEmbeddingEventHandler(this.mediator, this.debugMode);
|
|
18
|
+
// Add more handlers as you implement them
|
|
19
|
+
// this.handlers.screenshot = new ScreenshotEventHandler(this.mediator, this.debugMode);
|
|
20
|
+
// this.handlers.frameEmbedding = new FrameEmbeddingEventHandler(this.mediator, this.debugMode);
|
|
21
|
+
if (this.debugMode) {
|
|
22
|
+
console.log("HandlerRegistry: Initialized all event handlers");
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
setDebugMode(enabled) {
|
|
26
|
+
this.debugMode = enabled;
|
|
27
|
+
// Update debug mode for all handlers
|
|
28
|
+
Object.values(this.handlers).forEach(handler => {
|
|
29
|
+
if (typeof handler.setDebugMode === 'function') {
|
|
30
|
+
handler.setDebugMode(enabled);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/otel.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ContentProtector } from '@/core/index.js';
|
|
2
|
+
import type { ContentProtectionOptions } from '@/types/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Minimal span interface — matches @opentelemetry/api Span without requiring
|
|
5
|
+
* it as a dependency. Pass any object with addEvent() — including real OTel spans
|
|
6
|
+
* or a Blindspot route span from getRouteSpan().
|
|
7
|
+
*/
|
|
8
|
+
export interface SpanLike {
|
|
9
|
+
addEvent(name: string, attributes?: Record<string, string | number | boolean>): void;
|
|
10
|
+
}
|
|
11
|
+
export type SpanProvider = () => SpanLike | null | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Creates a ContentProtector with all callbacks wired to OTel span events.
|
|
14
|
+
*
|
|
15
|
+
* Pass any existing customHandlers in options — they run after the span event
|
|
16
|
+
* is recorded, so UI state updates and span recording both happen.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* // With Blindspot:
|
|
20
|
+
* import { getRouteSpan } from '@tindalabs/blindspot-web';
|
|
21
|
+
* const protector = attachShieldToSpan(options, () => getRouteSpan());
|
|
22
|
+
* protector.protect();
|
|
23
|
+
*/
|
|
24
|
+
export declare function attachShieldToSpan(options: ContentProtectionOptions, spanProvider: SpanProvider): ContentProtector;
|
package/dist/otel.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { ContentProtector } from '@/core/index.js';
|
|
2
|
+
function emit(provider, name, attrs) {
|
|
3
|
+
try {
|
|
4
|
+
provider()?.addEvent(name, attrs);
|
|
5
|
+
}
|
|
6
|
+
catch { /* never let telemetry crash the app */ }
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Creates a ContentProtector with all callbacks wired to OTel span events.
|
|
10
|
+
*
|
|
11
|
+
* Pass any existing customHandlers in options — they run after the span event
|
|
12
|
+
* is recorded, so UI state updates and span recording both happen.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* // With Blindspot:
|
|
16
|
+
* import { getRouteSpan } from '@tindalabs/blindspot-web';
|
|
17
|
+
* const protector = attachShieldToSpan(options, () => getRouteSpan());
|
|
18
|
+
* protector.protect();
|
|
19
|
+
*/
|
|
20
|
+
export function attachShieldToSpan(options, spanProvider) {
|
|
21
|
+
const existing = options.customHandlers ?? {};
|
|
22
|
+
const handlers = {
|
|
23
|
+
...existing,
|
|
24
|
+
onDevToolsOpen(isOpen) {
|
|
25
|
+
emit(spanProvider, isOpen ? 'shield.devtools.opened' : 'shield.devtools.closed');
|
|
26
|
+
existing.onDevToolsOpen?.(isOpen);
|
|
27
|
+
},
|
|
28
|
+
onSelectionAttempt(event) {
|
|
29
|
+
emit(spanProvider, 'shield.selection.attempted');
|
|
30
|
+
existing.onSelectionAttempt?.(event);
|
|
31
|
+
},
|
|
32
|
+
onContextMenuAttempt(event) {
|
|
33
|
+
emit(spanProvider, 'shield.context_menu.attempted');
|
|
34
|
+
existing.onContextMenuAttempt?.(event);
|
|
35
|
+
},
|
|
36
|
+
onPrintAttempt(event) {
|
|
37
|
+
emit(spanProvider, 'shield.print.attempted');
|
|
38
|
+
existing.onPrintAttempt?.(event);
|
|
39
|
+
},
|
|
40
|
+
onKeyboardShortcutBlocked(event) {
|
|
41
|
+
emit(spanProvider, 'shield.keyboard_shortcut.blocked', {
|
|
42
|
+
'shield.keyboard.key': event.key,
|
|
43
|
+
'shield.keyboard.code': event.code,
|
|
44
|
+
});
|
|
45
|
+
existing.onKeyboardShortcutBlocked?.(event);
|
|
46
|
+
},
|
|
47
|
+
onClipboardAttempt(event, action) {
|
|
48
|
+
emit(spanProvider, `shield.clipboard.${action}`);
|
|
49
|
+
existing.onClipboardAttempt?.(event, action);
|
|
50
|
+
},
|
|
51
|
+
onScreenshotAttempt(event) {
|
|
52
|
+
emit(spanProvider, 'shield.screenshot.attempted');
|
|
53
|
+
existing.onScreenshotAttempt?.(event);
|
|
54
|
+
},
|
|
55
|
+
onExtensionDetected(id, name, risk) {
|
|
56
|
+
emit(spanProvider, 'shield.extension.detected', {
|
|
57
|
+
'shield.extension.id': id,
|
|
58
|
+
'shield.extension.name': name,
|
|
59
|
+
'shield.extension.risk': risk,
|
|
60
|
+
});
|
|
61
|
+
existing.onExtensionDetected?.(id, name, risk);
|
|
62
|
+
},
|
|
63
|
+
onFrameEmbeddingDetected(isEmbedded, isExternal) {
|
|
64
|
+
if (isEmbedded) {
|
|
65
|
+
emit(spanProvider, 'shield.frame.embedding.detected', {
|
|
66
|
+
'shield.frame.external': isExternal,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
existing.onFrameEmbeddingDetected?.(isEmbedded, isExternal);
|
|
70
|
+
},
|
|
71
|
+
onProtectionBypassed(method, event) {
|
|
72
|
+
emit(spanProvider, 'shield.protection.bypassed', {
|
|
73
|
+
'shield.bypass.method': method,
|
|
74
|
+
});
|
|
75
|
+
existing.onProtectionBypassed?.(method, event);
|
|
76
|
+
},
|
|
77
|
+
onContentHidden(reason, target) {
|
|
78
|
+
emit(spanProvider, 'shield.content.hidden', { 'shield.hidden.reason': reason });
|
|
79
|
+
existing.onContentHidden?.(reason, target);
|
|
80
|
+
},
|
|
81
|
+
onContentRestored(target) {
|
|
82
|
+
emit(spanProvider, 'shield.content.restored');
|
|
83
|
+
existing.onContentRestored?.(target);
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
return new ContentProtector({ ...options, customHandlers: handlers });
|
|
87
|
+
}
|
|
@@ -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
|
+
}
|