devtools-guardian 1.0.1
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 +192 -0
- package/dist/index.d.mts +57 -0
- package/dist/index.d.ts +57 -0
- package/dist/index.js +657 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +628 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# DevTools Guardian 🛡️
|
|
2
|
+
|
|
3
|
+
[](https://opensource.org/licenses/ISC)
|
|
4
|
+
[](https://react.dev)
|
|
5
|
+
[](https://tsup.egoist.dev/)
|
|
6
|
+
|
|
7
|
+
**DevTools Guardian** is a lightweight, zero-dependency, and zero-configuration client-side security guard for React applications. It detects when a user opens browser Developer Tools and locks down the interface using an immersive, animated Matrix-inspired security warning overlay to protect your code, intellectual property, and static assets from inspection, cloning, and reverse-engineering.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Key Features
|
|
12
|
+
|
|
13
|
+
- **Multi-Heuristic DevTools Detection**:
|
|
14
|
+
- **Docked Mode**: Tracks browser window outer-to-inner aspect ratios (accounts for DPI scaling and device zoom).
|
|
15
|
+
- **Undocked Mode**: Uses a performance timing probe combined with controlled debugger statements.
|
|
16
|
+
- **Console Getter Probe**: Employs a blink-free lazy evaluation trick on the console object—triggers instantly when the console pane is rendered, without printing clutter or requiring console-clearing loops.
|
|
17
|
+
- **Vite & Webpack Dev Mode Bypasses**: Intelligent environment detector prevents debugger statement execution on `localhost`, local IPs (`192.168.x.x`, `10.x.x.x`, `172.x.x.x`), and standard node development runtimes. Developers can debug their code locally without getting trapped in warning loops.
|
|
18
|
+
- **Mobile & Touch-Screen Safeguards**: Automatically ignores dynamic address-bar viewport changes on touch screens (such as iOS Safari/Chrome scrolling adjustments) to eliminate false positives.
|
|
19
|
+
- **Zero-Config Stylesheet Injection**: Styles are bundled and injected dynamically. No manual `.css` imports required in consuming projects.
|
|
20
|
+
- **Keyboard Shortcut Interception**: Silently blocks inspection hotkeys:
|
|
21
|
+
- `F12`
|
|
22
|
+
- `Ctrl + Shift + I` / `Cmd + Option + I` (DevTools Open)
|
|
23
|
+
- `Ctrl + Shift + J` / `Cmd + Option + J` (Console Panel)
|
|
24
|
+
- `Ctrl + Shift + C` / `Cmd + Option + C` (Element Picker)
|
|
25
|
+
- `Ctrl + U` / `Cmd + Option + U` (View Source)
|
|
26
|
+
- `Ctrl + S` / `Cmd + S` (Save Page - blocked silently without triggering warning)
|
|
27
|
+
- **Built-in UI Guards**: Optional full-app text selection disabling and right-click context menu blocking.
|
|
28
|
+
- **React 18 & 19 Ready**: Out of the box support, complete with `"use client"` directives for seamless Next.js App Router integrations.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
Install using your preferred package manager:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# npm
|
|
38
|
+
npm install devtools-guardian
|
|
39
|
+
|
|
40
|
+
# pnpm
|
|
41
|
+
pnpm add devtools-guardian
|
|
42
|
+
|
|
43
|
+
# yarn
|
|
44
|
+
yarn add devtools-guardian
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Quick Start
|
|
50
|
+
|
|
51
|
+
### 1. Protect Your App (Provider Method)
|
|
52
|
+
|
|
53
|
+
The simplest way is to wrap your root layouts or main page tree inside `<DevToolsProtection />`.
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
import React from 'react';
|
|
57
|
+
import { DevToolsProtection } from 'devtools-guardian';
|
|
58
|
+
|
|
59
|
+
export default function App() {
|
|
60
|
+
return (
|
|
61
|
+
<DevToolsProtection overlay={true}>
|
|
62
|
+
<YourAppRoutes />
|
|
63
|
+
</DevToolsProtection>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 2. Custom Detection Trigger (Hook Method)
|
|
69
|
+
|
|
70
|
+
If you prefer custom actions (e.g., logging attempts, logging out users, hiding specific secret components) instead of displaying the default warning overlay, use the `useDevToolsDetector` hook:
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
import React, { useEffect } from 'react';
|
|
74
|
+
import { useDevToolsDetector } from 'devtools-guardian';
|
|
75
|
+
|
|
76
|
+
export default function SensitiveComponent() {
|
|
77
|
+
const isDevToolsOpen = useDevToolsDetector({
|
|
78
|
+
disableRightClick: true,
|
|
79
|
+
disableSelection: false, // allow user to select text
|
|
80
|
+
blockedKeys: ['F12', 'Ctrl+Shift+I'],
|
|
81
|
+
onDetect: () => {
|
|
82
|
+
console.warn('Suspicious activity flagged!');
|
|
83
|
+
// Trigger API reports or logout here
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<div>
|
|
89
|
+
{isDevToolsOpen ? (
|
|
90
|
+
<div className="secured-message">Sensitive content has been hidden.</div>
|
|
91
|
+
) : (
|
|
92
|
+
<div className="sensitive-data">Confidential Financial Dashboard</div>
|
|
93
|
+
)}
|
|
94
|
+
</div>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 3. Display warning card manually
|
|
100
|
+
|
|
101
|
+
You can render the Matrix Warning screen directly when needed.
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
import React, { useState } from 'react';
|
|
105
|
+
import { DevToolsWarningOverlay } from 'devtools-guardian';
|
|
106
|
+
|
|
107
|
+
export default function DemoPage() {
|
|
108
|
+
const [showWarning, setShowWarning] = useState(false);
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<div>
|
|
112
|
+
<button onClick={() => setShowWarning(true)}>Simulate Defense System</button>
|
|
113
|
+
|
|
114
|
+
{showWarning && (
|
|
115
|
+
<DevToolsWarningOverlay onClose={() => setShowWarning(false)} />
|
|
116
|
+
)}
|
|
117
|
+
</div>
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## API Reference
|
|
125
|
+
|
|
126
|
+
### `<DevToolsProtection />`
|
|
127
|
+
|
|
128
|
+
| Prop | Type | Default | Description |
|
|
129
|
+
|---|---|---|---|
|
|
130
|
+
| `children` | `React.ReactNode` | *Required* | The elements wrapped by the protection layer. |
|
|
131
|
+
| `overlay` | `boolean` | `true` | When `true`, automatically renders the `<DevToolsWarningOverlay />` dialog when DevTools are detected. |
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
### `useDevToolsDetector(options)`
|
|
136
|
+
|
|
137
|
+
| Option | Type | Default | Description |
|
|
138
|
+
|---|---|---|---|
|
|
139
|
+
| `blockedKeys` | `string[]` | `['Ctrl+Shift+I', 'Ctrl+Shift+J', 'Ctrl+Shift+C', 'Ctrl+U', 'Ctrl+S']` | Keys/shortcuts intercepted and cancelled. |
|
|
140
|
+
| `disableRightClick` | `boolean` | `true` | Disables browser right-click context menus. |
|
|
141
|
+
| `disableSelection` | `boolean` | `true` | Adds CSS user-select styles to prevent layout copying. |
|
|
142
|
+
| `onDetect` | `() => void` | `undefined` | Callback fired when DevTools is first opened. |
|
|
143
|
+
| `onClose` | `() => void` | `undefined` | Callback fired when DevTools is closed. |
|
|
144
|
+
| `pollInterval` | `number` | `1500` | Frequency in ms to check DevTools status. |
|
|
145
|
+
| `thresholdBuffer` | `number` | `0` | Extra pixel offset buffer for docked dimensions. Increase this on custom Electron/web view wrappers. |
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
### `<DevToolsWarningOverlay />`
|
|
150
|
+
|
|
151
|
+
| Prop | Type | Default | Description |
|
|
152
|
+
|---|---|---|---|
|
|
153
|
+
| `onClose` | `() => void` | `undefined` | Callback passed to the dialog dismiss button. If not provided, the "Close & return" button will not render. |
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## How It Works Under the Hood
|
|
158
|
+
|
|
159
|
+
1. **Docked Window Differences**:
|
|
160
|
+
Comparing `window.outerWidth` vs `window.innerWidth` and `window.outerHeight` vs `window.innerHeight`. The library applies a high-DPI scaling factor (`window.devicePixelRatio`) to avoid false alarms during page zooming.
|
|
161
|
+
2. **Console Lazy Evaluation (Blink-Free)**:
|
|
162
|
+
A lightweight probe object is sent to the console via `console.log`. The object overrides `Symbol.toPrimitive` and `toString`. In modern browsers, when DevTools is closed, the console logs are ignored and the methods are never evaluated. When DevTools is opened, the browser's console processes and renders the logged object, which immediately triggers our hook's tracking state.
|
|
163
|
+
3. **Protected Threading & Exception Safety**:
|
|
164
|
+
Overriding native browser logs temporarily is dangerous. DevTools Guardian executes the probe inside a strict `try...finally` block, ensuring that the original console properties are instantly restored even if third-party console decorators throw unexpected errors.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Local Development & Testing
|
|
169
|
+
|
|
170
|
+
We have built a developer playground using Vite. To run it:
|
|
171
|
+
|
|
172
|
+
1. Clone this repository.
|
|
173
|
+
2. Install local workspace dependencies:
|
|
174
|
+
```bash
|
|
175
|
+
npm install
|
|
176
|
+
```
|
|
177
|
+
3. Run the development server:
|
|
178
|
+
```bash
|
|
179
|
+
npm run dev
|
|
180
|
+
```
|
|
181
|
+
4. Build the production package bundles:
|
|
182
|
+
```bash
|
|
183
|
+
npm run build
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Credits
|
|
189
|
+
Built with ❤️ by [Ali Arshad](https://github.com/Ali-Arshad-110). Connect with me on [LinkedIn](https://www.linkedin.com/in/aliarshad110).
|
|
190
|
+
|
|
191
|
+
## License
|
|
192
|
+
This project is licensed under the [ISC License](LICENSE).
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
interface DevToolsDetectorOptions {
|
|
5
|
+
/** Keyboard shortcuts to intercept. Default covers common DevTools keys. */
|
|
6
|
+
blockedKeys?: string[];
|
|
7
|
+
/** Disable right-click context menu. Default: true */
|
|
8
|
+
disableRightClick?: boolean;
|
|
9
|
+
/** Disable text selection on the page. Default: true */
|
|
10
|
+
disableSelection?: boolean;
|
|
11
|
+
/** Called once when DevTools is first detected as open. */
|
|
12
|
+
onDetect?: () => void;
|
|
13
|
+
/** Called once when DevTools is detected as closed. */
|
|
14
|
+
onClose?: () => void;
|
|
15
|
+
/** Polling interval in ms. Default: 1500 */
|
|
16
|
+
pollInterval?: number;
|
|
17
|
+
/**
|
|
18
|
+
* Extra px added to both dimension thresholds.
|
|
19
|
+
* Raise this on layouts with large chrome (e.g. electron shells). Default: 0
|
|
20
|
+
*/
|
|
21
|
+
thresholdBuffer?: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* useDevToolsDetector
|
|
25
|
+
|
|
26
|
+
*
|
|
27
|
+
* Detects whether the browser's DevTools panel is open using three
|
|
28
|
+
* complementary heuristics:
|
|
29
|
+
* 1. Window outer/inner size differential (docked panel)
|
|
30
|
+
* 2. Console Image-getter trick (Chrome / Firefox console evaluation)
|
|
31
|
+
* 3. Optional debugger timing check (undocked panel, production only)
|
|
32
|
+
*
|
|
33
|
+
* Additionally provides keyboard-shortcut blocking and UX protections.
|
|
34
|
+
*
|
|
35
|
+
* @returns `true` when DevTools is considered open, `false` otherwise.
|
|
36
|
+
*/
|
|
37
|
+
declare function useDevToolsDetector(options?: DevToolsDetectorOptions): boolean;
|
|
38
|
+
|
|
39
|
+
interface Props {
|
|
40
|
+
children: React.ReactNode;
|
|
41
|
+
overlay?: boolean;
|
|
42
|
+
}
|
|
43
|
+
declare const DevToolsProtection: ({ children, overlay, }: Props) => react_jsx_runtime.JSX.Element;
|
|
44
|
+
|
|
45
|
+
interface DevToolsWarningOverlayProps {
|
|
46
|
+
/** Optional handler called when the user dismisses the overlay. */
|
|
47
|
+
onClose?: () => void;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* DevToolsWarningOverlay
|
|
51
|
+
*
|
|
52
|
+
* Full-screen security overlay shown when DevTools are detected.
|
|
53
|
+
* Runs a 3-step animated scan sequence before revealing the warning card.
|
|
54
|
+
*/
|
|
55
|
+
declare const DevToolsWarningOverlay: React.FC<DevToolsWarningOverlayProps>;
|
|
56
|
+
|
|
57
|
+
export { type DevToolsDetectorOptions, DevToolsProtection, DevToolsWarningOverlay, useDevToolsDetector };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
interface DevToolsDetectorOptions {
|
|
5
|
+
/** Keyboard shortcuts to intercept. Default covers common DevTools keys. */
|
|
6
|
+
blockedKeys?: string[];
|
|
7
|
+
/** Disable right-click context menu. Default: true */
|
|
8
|
+
disableRightClick?: boolean;
|
|
9
|
+
/** Disable text selection on the page. Default: true */
|
|
10
|
+
disableSelection?: boolean;
|
|
11
|
+
/** Called once when DevTools is first detected as open. */
|
|
12
|
+
onDetect?: () => void;
|
|
13
|
+
/** Called once when DevTools is detected as closed. */
|
|
14
|
+
onClose?: () => void;
|
|
15
|
+
/** Polling interval in ms. Default: 1500 */
|
|
16
|
+
pollInterval?: number;
|
|
17
|
+
/**
|
|
18
|
+
* Extra px added to both dimension thresholds.
|
|
19
|
+
* Raise this on layouts with large chrome (e.g. electron shells). Default: 0
|
|
20
|
+
*/
|
|
21
|
+
thresholdBuffer?: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* useDevToolsDetector
|
|
25
|
+
|
|
26
|
+
*
|
|
27
|
+
* Detects whether the browser's DevTools panel is open using three
|
|
28
|
+
* complementary heuristics:
|
|
29
|
+
* 1. Window outer/inner size differential (docked panel)
|
|
30
|
+
* 2. Console Image-getter trick (Chrome / Firefox console evaluation)
|
|
31
|
+
* 3. Optional debugger timing check (undocked panel, production only)
|
|
32
|
+
*
|
|
33
|
+
* Additionally provides keyboard-shortcut blocking and UX protections.
|
|
34
|
+
*
|
|
35
|
+
* @returns `true` when DevTools is considered open, `false` otherwise.
|
|
36
|
+
*/
|
|
37
|
+
declare function useDevToolsDetector(options?: DevToolsDetectorOptions): boolean;
|
|
38
|
+
|
|
39
|
+
interface Props {
|
|
40
|
+
children: React.ReactNode;
|
|
41
|
+
overlay?: boolean;
|
|
42
|
+
}
|
|
43
|
+
declare const DevToolsProtection: ({ children, overlay, }: Props) => react_jsx_runtime.JSX.Element;
|
|
44
|
+
|
|
45
|
+
interface DevToolsWarningOverlayProps {
|
|
46
|
+
/** Optional handler called when the user dismisses the overlay. */
|
|
47
|
+
onClose?: () => void;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* DevToolsWarningOverlay
|
|
51
|
+
*
|
|
52
|
+
* Full-screen security overlay shown when DevTools are detected.
|
|
53
|
+
* Runs a 3-step animated scan sequence before revealing the warning card.
|
|
54
|
+
*/
|
|
55
|
+
declare const DevToolsWarningOverlay: React.FC<DevToolsWarningOverlayProps>;
|
|
56
|
+
|
|
57
|
+
export { type DevToolsDetectorOptions, DevToolsProtection, DevToolsWarningOverlay, useDevToolsDetector };
|