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.
Files changed (58) hide show
  1. package/README.md +22 -0
  2. package/dist/core/mediator/handlers/baseEventHandler.d.ts +65 -0
  3. package/dist/core/mediator/handlers/baseEventHandler.js +99 -0
  4. package/dist/core/mediator/handlers/index.d.ts +9 -0
  5. package/dist/core/mediator/handlers/index.js +34 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +1 -0
  8. package/dist/otel.d.ts +24 -0
  9. package/dist/otel.js +87 -0
  10. package/dist/strategies/AbstractStrategy.mediator.d.ts +162 -0
  11. package/dist/strategies/AbstractStrategy.mediator.js +349 -0
  12. package/dist/strategies/DevToolsStrategy copy.d.ts +85 -0
  13. package/dist/strategies/DevToolsStrategy copy.js +362 -0
  14. package/dist/strategies/DevToolsStrategy-detectorManager.d.ts +70 -0
  15. package/dist/strategies/DevToolsStrategy-detectorManager.js +309 -0
  16. package/dist/strategies/DevToolsStrategy-simple.d.ts +75 -0
  17. package/dist/strategies/DevToolsStrategy-simple.js +366 -0
  18. package/dist/strategies/StrategyRegistry.d.ts +133 -0
  19. package/dist/strategies/StrategyRegistry.js +379 -0
  20. package/dist/utils/base/LoggableComponent.d.ts +62 -0
  21. package/dist/utils/base/LoggableComponent.js +95 -0
  22. package/dist/utils/debuggerDetector/debuggerDetectionWorker.d.ts +6 -0
  23. package/dist/utils/debuggerDetector/debuggerDetectionWorker.js +24 -0
  24. package/dist/utils/debuggerDetector/debuggerDetector.d.ts +55 -0
  25. package/dist/utils/debuggerDetector/debuggerDetector.js +158 -0
  26. package/dist/utils/debuggerDetector/firefoxDetector.d.ts +8 -0
  27. package/dist/utils/debuggerDetector/firefoxDetector.js +64 -0
  28. package/dist/utils/detection.d.ts +29 -0
  29. package/dist/utils/detection.js +267 -0
  30. package/dist/utils/detectors/debuggerDetectionWorker.d.ts +6 -0
  31. package/dist/utils/detectors/debuggerDetectionWorker.js +24 -0
  32. package/dist/utils/detectors/firefoxDetector.d.ts +8 -0
  33. package/dist/utils/detectors/firefoxDetector.js +64 -0
  34. package/dist/utils/logging/LogLevel.d.ts +21 -0
  35. package/dist/utils/logging/LogLevel.js +46 -0
  36. package/dist/utils/logging/LoggingConfig.d.ts +68 -0
  37. package/dist/utils/logging/LoggingConfig.js +64 -0
  38. package/dist/utils/logging/LoggingFactory.d.ts +22 -0
  39. package/dist/utils/logging/LoggingFactory.js +61 -0
  40. package/dist/utils/logging/LoggingService.d.ts +235 -0
  41. package/dist/utils/logging/LoggingService.js +385 -0
  42. package/dist/utils/logging/SimpleLoggingService.d.ts +39 -0
  43. package/dist/utils/logging/SimpleLoggingService.js +58 -0
  44. package/dist/utils/logging/advanced/LogLevel.d.ts +21 -0
  45. package/dist/utils/logging/advanced/LogLevel.js +46 -0
  46. package/dist/utils/logging/advanced/LoggingConfig.d.ts +68 -0
  47. package/dist/utils/logging/advanced/LoggingConfig.js +64 -0
  48. package/dist/utils/logging/advanced/LoggingFactory.d.ts +22 -0
  49. package/dist/utils/logging/advanced/LoggingFactory.js +61 -0
  50. package/dist/utils/logging/advanced/LoggingService.d.ts +235 -0
  51. package/dist/utils/logging/advanced/LoggingService.js +385 -0
  52. package/dist/utils/protectedContentManager-simple.d.ts +86 -0
  53. package/dist/utils/protectedContentManager-simple.js +180 -0
  54. package/dist/utils/securityOverlayManager-observer-pause.d.ts +283 -0
  55. package/dist/utils/securityOverlayManager-observer-pause.js +878 -0
  56. package/dist/utils/securityOverlayManager-simple.d.ts +197 -0
  57. package/dist/utils/securityOverlayManager-simple.js +552 -0
  58. package/package.json +1 -1
@@ -0,0 +1,362 @@
1
+ import { isBrowser } from "../utils/detection";
2
+ import { getOrientationType } from "../utils/orientation";
3
+ import { ProtectedContentManager } from "../utils/protectedContentManager";
4
+ import { SecurityOverlayManager } from "../utils/securityOverlayManager";
5
+ import { intervalManager } from "../utils/intervalManager";
6
+ import { AbstractStrategy, StrategyErrorType } from "./AbstractStrategy";
7
+ /**
8
+ * Strategy for detecting and responding to DevTools usage
9
+ */
10
+ export class DevToolsStrategy extends AbstractStrategy {
11
+ /**
12
+ * Create a new DevToolsStrategy
13
+ * @param options Options for customizing the DevTools protection
14
+ * @param targetElement Element containing sensitive content
15
+ * @param customHandler Optional custom handler for DevTools detection
16
+ * @param debugMode Enable debug mode for troubleshooting
17
+ */
18
+ constructor(options, targetElement = null, customHandler, debugMode = false) {
19
+ super("DevToolsStrategy", debugMode);
20
+ this.intervalId = null;
21
+ this.taskId = null;
22
+ this.isDevToolsOpen = false;
23
+ this.targetElement = null;
24
+ this.contentManager = null;
25
+ this.resizeEventId = "";
26
+ // Store dimensions
27
+ this.originalWidth = 0;
28
+ this.originalHeight = 0;
29
+ // Track orientation
30
+ this.previousOrientation = null;
31
+ this.options = {
32
+ title: "Developer Tools Detected",
33
+ message: "For security reasons, this content is not available while developer tools are open.",
34
+ secondaryMessage: "Please close developer tools to continue viewing this content.",
35
+ textColor: "white",
36
+ backgroundColor: "rgba(255, 0, 0, 0.7)",
37
+ checkFrequency: 1000,
38
+ ...options,
39
+ };
40
+ this.targetElement = targetElement;
41
+ this.customHandler = customHandler;
42
+ this.resizeHandler = this.handleResize.bind(this);
43
+ // Initialize content manager if target element is provided
44
+ if (targetElement) {
45
+ this.contentManager = new ProtectedContentManager(targetElement, debugMode);
46
+ }
47
+ // Initialize overlay manager
48
+ this.overlayManager = new SecurityOverlayManager(debugMode);
49
+ this.log("Initialized with checkFrequency:", this.options.checkFrequency);
50
+ }
51
+ /**
52
+ * Detect if DevTools is open based on window dimensions
53
+ * @returns True if DevTools is likely open, false otherwise
54
+ */
55
+ detectDevTools() {
56
+ return (this.safeExecute("detectDevTools", StrategyErrorType.APPLICATION, () => {
57
+ if (typeof window === "undefined")
58
+ return false;
59
+ const currentWidth = window.innerWidth;
60
+ const currentHeight = window.innerHeight;
61
+ const currentOrientation = getOrientationType();
62
+ this.log(`Current dimensions: ${currentWidth}x${currentHeight}, original: ${this.originalWidth}x${this.originalHeight}`);
63
+ this.log(`Current orientation: ${currentOrientation}, previous: ${this.previousOrientation}`);
64
+ // Calculate differences
65
+ const widthDifference = currentWidth - this.originalWidth;
66
+ const heightDifference = currentHeight - this.originalHeight;
67
+ // Check if orientation has changed
68
+ const orientationChanged = this.previousOrientation !== null && this.previousOrientation !== currentOrientation;
69
+ // If orientation has changed, update our reference dimensions
70
+ if (orientationChanged) {
71
+ this.log(`Orientation changed from ${this.previousOrientation} to ${currentOrientation}`);
72
+ // Update the original dimensions to the current ones when orientation changes
73
+ this.originalWidth = currentWidth;
74
+ this.originalHeight = currentHeight;
75
+ // Update previous orientation
76
+ this.previousOrientation = currentOrientation;
77
+ // Don't trigger DevTools detection on orientation change
78
+ return false;
79
+ }
80
+ // Only consider DevTools open if dimensions get smaller (with a small tolerance)
81
+ // This prevents false positives when closing DevTools that were open on page load
82
+ if (widthDifference < -20 || heightDifference < -20) {
83
+ // If dimensions are significantly smaller, DevTools is likely open
84
+ this.log("Significant size reduction detected, DevTools likely open");
85
+ return true;
86
+ }
87
+ else {
88
+ // If dimensions are larger or about the same, DevTools is likely closed
89
+ // Update the original dimensions to the current ones if they're larger
90
+ // This ensures we always compare against the largest known viewport size
91
+ if (currentWidth > this.originalWidth) {
92
+ this.originalWidth = currentWidth;
93
+ }
94
+ if (currentHeight > this.originalHeight) {
95
+ this.originalHeight = currentHeight;
96
+ }
97
+ return false;
98
+ }
99
+ }) || false); // Return false as fallback if error occurs
100
+ }
101
+ /**
102
+ * Handle window resize events to detect DevTools
103
+ */
104
+ handleResize() {
105
+ return this.safeExecute("handleResize", StrategyErrorType.EVENT_HANDLING, () => {
106
+ const devToolsOpen = this.detectDevTools();
107
+ this.log("Resize handler called, devToolsOpen:", devToolsOpen, "current state:", this.isDevToolsOpen);
108
+ // Update state and take action if state has changed
109
+ if (devToolsOpen !== this.isDevToolsOpen) {
110
+ this.isDevToolsOpen = devToolsOpen;
111
+ this.log(`DevTools state changed: ${devToolsOpen ? "open" : "closed"}`);
112
+ if (devToolsOpen) {
113
+ this.applyDevToolsProtection();
114
+ }
115
+ else {
116
+ this.removeDevToolsProtection();
117
+ }
118
+ // Call custom handler if provided
119
+ if (this.customHandler) {
120
+ this.customHandler(devToolsOpen);
121
+ }
122
+ }
123
+ });
124
+ }
125
+ /**
126
+ * Start monitoring for DevTools usage
127
+ */
128
+ startMonitoring() {
129
+ return this.safeExecute("startMonitoring", StrategyErrorType.APPLICATION, () => {
130
+ if (typeof window === "undefined")
131
+ return;
132
+ this.log("Starting DevTools monitoring");
133
+ // Store initial dimensions
134
+ this.originalWidth = window.innerWidth;
135
+ this.originalHeight = window.innerHeight;
136
+ // Store initial orientation
137
+ this.previousOrientation = getOrientationType();
138
+ this.log(`Initial dimensions: ${this.originalWidth}x${this.originalHeight}`);
139
+ this.log(`Initial orientation: ${this.previousOrientation}`);
140
+ // Add resize event listener using our registerEvent method
141
+ this.resizeEventId = this.registerEvent(window, "resize", this.resizeHandler, { priority: 10 });
142
+ // Register with IntervalManager for periodic checks
143
+ this.taskId = intervalManager.registerTask("devtools-detection", () => this.safeExecute("intervalTask", StrategyErrorType.APPLICATION, () => {
144
+ const devToolsOpen = this.detectDevTools();
145
+ // Force state update and action if state has changed
146
+ if (devToolsOpen !== this.isDevToolsOpen) {
147
+ this.isDevToolsOpen = devToolsOpen;
148
+ this.log(`DevTools state changed: ${devToolsOpen ? "open" : "closed"}`);
149
+ if (devToolsOpen) {
150
+ this.applyDevToolsProtection();
151
+ }
152
+ else {
153
+ this.removeDevToolsProtection();
154
+ }
155
+ if (this.customHandler) {
156
+ this.customHandler(devToolsOpen);
157
+ }
158
+ }
159
+ // Always check overlay state through the overlay manager
160
+ if (this.isDevToolsOpen) {
161
+ this.overlayManager.checkAndRestoreOverlay();
162
+ }
163
+ }), this.options.checkFrequency);
164
+ // Force initial check
165
+ this.handleResize();
166
+ });
167
+ }
168
+ /**
169
+ * Apply DevTools protection by creating overlay and event blocker
170
+ */
171
+ applyDevToolsProtection() {
172
+ return this.safeExecute("applyDevToolsProtection", StrategyErrorType.APPLICATION, () => {
173
+ if (!isBrowser())
174
+ return;
175
+ // Hide sensitive content
176
+ this.hideSensitiveContent();
177
+ // Create overlay using the overlay manager
178
+ this.overlayManager.showOverlay({
179
+ title: this.options.title,
180
+ message: this.options.message,
181
+ secondaryMessage: this.options.secondaryMessage,
182
+ backgroundColor: this.options.backgroundColor,
183
+ textColor: this.options.textColor,
184
+ blockEvents: true, // Block all events
185
+ autoRestore: true, // Restore overlay if removed from DOM
186
+ });
187
+ this.log("DevTools protection applied");
188
+ });
189
+ }
190
+ /**
191
+ * Hide sensitive content when DevTools is open
192
+ */
193
+ hideSensitiveContent() {
194
+ return this.safeExecute("hideSensitiveContent", StrategyErrorType.APPLICATION, () => {
195
+ if (!this.targetElement || !this.contentManager)
196
+ return;
197
+ this.contentManager.hideContent({
198
+ title: this.options.title,
199
+ message: this.options.message,
200
+ secondaryMessage: this.options.secondaryMessage,
201
+ textColor: "black",
202
+ backgroundColor: "rgba(0, 0, 0, 0.05)",
203
+ });
204
+ this.log("Sensitive content hidden");
205
+ });
206
+ }
207
+ /**
208
+ * Restore sensitive content when DevTools is closed
209
+ */
210
+ restoreSensitiveContent() {
211
+ return this.safeExecute("restoreSensitiveContent", StrategyErrorType.REMOVAL, () => {
212
+ if (!this.contentManager)
213
+ return;
214
+ this.contentManager.restoreContent();
215
+ this.log("Sensitive content restored");
216
+ });
217
+ }
218
+ /**
219
+ * Remove DevTools protection
220
+ */
221
+ removeDevToolsProtection() {
222
+ return this.safeExecute("removeDevToolsProtection", StrategyErrorType.REMOVAL, () => {
223
+ if (typeof document === "undefined")
224
+ return;
225
+ // Restore sensitive content
226
+ this.restoreSensitiveContent();
227
+ // Remove overlay using the overlay manager
228
+ this.overlayManager.removeOverlay();
229
+ this.log("DevTools protection removed");
230
+ });
231
+ }
232
+ /**
233
+ * Apply the protection strategy
234
+ */
235
+ apply() {
236
+ return this.safeExecute("apply", StrategyErrorType.APPLICATION, () => {
237
+ if (this.isAppliedFlag) {
238
+ this.log("Protection already applied");
239
+ return;
240
+ }
241
+ this.startMonitoring();
242
+ this.isAppliedFlag = true;
243
+ this.log("Protection applied");
244
+ });
245
+ }
246
+ /**
247
+ * Remove the protection strategy
248
+ * Override the base implementation to handle additional cleanup
249
+ */
250
+ remove() {
251
+ return this.safeExecute("remove", StrategyErrorType.REMOVAL, () => {
252
+ if (!this.isAppliedFlag) {
253
+ this.log("Protection not applied");
254
+ return;
255
+ }
256
+ // Clear interval via IntervalManager
257
+ if (this.taskId !== null) {
258
+ intervalManager.unregisterTask(this.taskId);
259
+ this.taskId = null;
260
+ this.log("Interval task unregistered");
261
+ }
262
+ // Also clear the old interval for backwards compatibility or if both are used
263
+ if (this.intervalId !== null && typeof window !== "undefined") {
264
+ window.clearInterval(this.intervalId);
265
+ this.intervalId = null;
266
+ this.log("Legacy interval cleared");
267
+ }
268
+ // Call the parent class remove method to handle event cleanup
269
+ super.remove();
270
+ // Restore content if it was hidden
271
+ this.restoreSensitiveContent();
272
+ // Remove overlay and blocker
273
+ this.removeDevToolsProtection();
274
+ this.isAppliedFlag = false;
275
+ this.isDevToolsOpen = false;
276
+ this.log("Protection removed");
277
+ });
278
+ }
279
+ /**
280
+ * Update DevTools protection options
281
+ * @param options New options
282
+ */
283
+ updateOptions(options) {
284
+ return this.safeExecute("updateOptions", StrategyErrorType.OPTION_UPDATE, () => {
285
+ const typedOptions = options;
286
+ this.log("Updating options", typedOptions);
287
+ // Store previous options for comparison
288
+ const previousOptions = { ...this.options };
289
+ this.options = {
290
+ ...this.options,
291
+ ...typedOptions,
292
+ };
293
+ // If protection is already applied, update the overlay if needed
294
+ if (this.isAppliedFlag && this.isDevToolsOpen) {
295
+ // Check if any visual options changed
296
+ const visualOptionsChanged = previousOptions.title !== this.options.title ||
297
+ previousOptions.message !== this.options.message ||
298
+ previousOptions.secondaryMessage !== this.options.secondaryMessage ||
299
+ previousOptions.backgroundColor !== this.options.backgroundColor ||
300
+ previousOptions.textColor !== this.options.textColor;
301
+ if (visualOptionsChanged) {
302
+ this.removeDevToolsProtection();
303
+ this.applyDevToolsProtection();
304
+ this.log("Reapplied protection with updated visual options");
305
+ }
306
+ }
307
+ // Update check frequency if it changed
308
+ if (typedOptions.checkFrequency &&
309
+ this.taskId !== null &&
310
+ previousOptions.checkFrequency !== typedOptions.checkFrequency) {
311
+ // Unregister and re-register with new frequency
312
+ intervalManager.unregisterTask(this.taskId);
313
+ this.taskId = intervalManager.registerTask("devtools-detection", () => this.safeExecute("intervalTask", StrategyErrorType.APPLICATION, () => {
314
+ const devToolsOpen = this.detectDevTools();
315
+ if (devToolsOpen !== this.isDevToolsOpen) {
316
+ this.isDevToolsOpen = devToolsOpen;
317
+ if (devToolsOpen) {
318
+ this.applyDevToolsProtection();
319
+ }
320
+ else {
321
+ this.removeDevToolsProtection();
322
+ }
323
+ if (this.customHandler) {
324
+ this.customHandler(devToolsOpen);
325
+ }
326
+ }
327
+ if (this.isDevToolsOpen) {
328
+ this.overlayManager.checkAndRestoreOverlay();
329
+ }
330
+ }), this.options.checkFrequency);
331
+ this.log(`Check frequency updated to ${this.options.checkFrequency}ms`);
332
+ }
333
+ });
334
+ }
335
+ /**
336
+ * Set debug mode
337
+ * @param enabled Whether debug mode should be enabled
338
+ */
339
+ setDebugMode(enabled) {
340
+ return this.safeExecute("setDebugMode", StrategyErrorType.OPTION_UPDATE, () => {
341
+ super.setDebugMode(enabled);
342
+ // Also update debug mode for managers
343
+ if (this.contentManager && this.targetElement) {
344
+ this.contentManager = new ProtectedContentManager(this.targetElement, enabled);
345
+ }
346
+ this.overlayManager = new SecurityOverlayManager(enabled);
347
+ });
348
+ }
349
+ /**
350
+ * Check if strategy is applied
351
+ */
352
+ isApplied() {
353
+ return this.isAppliedFlag;
354
+ }
355
+ /**
356
+ * Check if debug mode is enabled
357
+ * @returns True if debug mode is enabled
358
+ */
359
+ isDebugEnabled() {
360
+ return this.debugMode;
361
+ }
362
+ }
@@ -0,0 +1,70 @@
1
+ import type { CustomEventHandlers, DevToolsOptions } from "../types";
2
+ import { AbstractStrategy } from "./AbstractStrategy";
3
+ /**
4
+ * Strategy for detecting and responding to DevTools usage
5
+ */
6
+ export declare class DevToolsStrategy extends AbstractStrategy {
7
+ private taskId;
8
+ private customHandler?;
9
+ private isDevToolsOpen;
10
+ private targetElement;
11
+ private options;
12
+ private contentManager;
13
+ private overlayManager;
14
+ private detectorManager;
15
+ /**
16
+ * Create a new DevToolsStrategy
17
+ * @param options Options for customizing the DevTools protection
18
+ * @param targetElement Element containing sensitive content
19
+ * @param customHandler Optional custom handler for DevTools detection
20
+ * @param debugMode Enable debug mode for troubleshooting
21
+ */
22
+ constructor(options?: DevToolsOptions, targetElement?: HTMLElement | null, customHandler?: CustomEventHandlers["onDevToolsOpen"], debugMode?: boolean);
23
+ /**
24
+ * Initialize the detector manager
25
+ */
26
+ private initDetectorManager;
27
+ /**
28
+ * Handle DevTools state changes from any detection method
29
+ */
30
+ private handleDevToolsStateChange;
31
+ /**
32
+ * Start monitoring for DevTools usage
33
+ */
34
+ private startMonitoring;
35
+ /**
36
+ * Apply DevTools protection by creating overlay and event blocker
37
+ */
38
+ private applyDevToolsProtection;
39
+ /**
40
+ * Hide sensitive content when DevTools is open
41
+ */
42
+ private hideSensitiveContent;
43
+ /**
44
+ * Restore sensitive content when DevTools is closed
45
+ */
46
+ private restoreSensitiveContent;
47
+ /**
48
+ * Remove DevTools protection
49
+ */
50
+ private removeDevToolsProtection;
51
+ /**
52
+ * Apply the protection strategy
53
+ */
54
+ apply(): void;
55
+ /**
56
+ * Remove the protection strategy
57
+ * Override the base implementation to handle additional cleanup
58
+ */
59
+ remove(): void;
60
+ /**
61
+ * Update DevTools protection options
62
+ * @param options New options
63
+ */
64
+ updateOptions(options: Record<string, unknown>): void;
65
+ /**
66
+ * Set debug mode
67
+ * @param enabled Whether debug mode should be enabled
68
+ */
69
+ setDebugMode(enabled: boolean): void;
70
+ }