GitHub: StateGuard.js
Stop users from messing with your UI logic via the console.
StateGuard.js is a lightweight utility that locks DOM element attributes. If a user tries to remove a disabled attribute, change a class, or inject an onclick event via DevTools, StateGuard detects it and reverts the change in milliseconds.
MutationObserver for near-instant attribute restoration.Snapshotting: The library takes a “Source of Truth” snapshot of an element’s attributes upon initialization.
The Guard: A MutationObserver watches the element 24/7. If an attribute is changed manually, it is instantly reverted to the snapshot.
Programmatic Gateway: Authorized changes must pass through the .update() method, which temporarily unlocks the element and updates the snapshot.
Include the minified version of StateGuard.js via CDN:
<script src="https://cdn.jsdelivr.net/npm/@rsuthar/state-guard-js/dist/state-guard.min.js"></script>
Install the package via npm:
npm install @rsuthar/state-guard-js
yarn add @rsuthar/state-guard-js
pnpm add @rsuthar/state-guard-js
StateGuard.protect(selector, options) Initializes protection on one or more elements.
| Property | Type | Default | Description |
|---|---|---|---|
| selector | string | Required | “CSS selector (e.g., #btn, .admin-fields).” |
| attributes | array or string,’all’,”List of attributes to protect (e.g., [‘class’, ‘disabled’]).” | ||
| maxAttempts | number,3,Number of manual changes allowed before triggering a violation. | ||
| onViolation | function,null,Callback executed when maxAttempts is reached. |
Key Features
Protect any element using standard CSS selectors.
StateGuard.protect('.secure-action', {
attributes: ['disabled', 'class', 'onclick'],
maxAttempts: 3,
onViolation: (el, count) => {
console.error("Reporting tamper attempt to server...");
// Send the report to your backend
fetch('/api/security/log-tamper', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
elementId: el.id || 'unnamed-element',
elementTag: el.tagName,
attempts: count,
timestamp: new Date().toISOString(),
userAgent: navigator.userAgent
})
})
.then(() => {
if (count > 5) {
alert("Security policy violation. This session will be terminated.");
window.location.href = '/logout';
}
});
}
});
The hook manages the lifecycle of the observer and ensures it cleans up when the component unmounts.
const { elementRef, safeUpdate } = useStateGuard({ attributes: ['class'] });
// Use safeUpdate to modify the element without triggering the guard
const handleUnlock = () => {
safeUpdate((el) => el.classList.remove('locked'));
};
Apply protection declaratively in your templates.
<button appStateGuard [protectedAttributes]="['disabled']" (violation)="logIt($event)">
Secure Action
</button>
npm run obfuscate before deploying. This makes it incredibly difficult for attackers to find the “unlock” logic in your source code.debugger statement if DevTools are opened while the script is running.To verify that the protection is active, run the included Jest suite:
npm test
This suite simulates a user attempting to delete attributes via the console and confirms the library restores them within the 100ms threshold.
Here are the official Release Notes for your version 1.0.0 launch. You can paste these directly into the “Releases” section of your GitHub repository.
**🚀 Release v1.0.0: StateGuard.js Initial Launch We are excited to announce the first stable release of StateGuard.js, a proactive security utility designed to harden client-side UI logic and prevent manual DOM tampering.
🌟 Features
📦 Installation Download the dist/state-guard.obf.js for production.
Initialize with StateGuard.protect(selector, options).
🛡️ Best Practices for this Version Obfuscate always: Never use the src/ files in a public production environment.
Update Gateway: Always use the .update() or safeUpdate methods to modify protected elements programmatically to avoid “infinite revert” loops.
npm init -y in your folder and paste the package.json content.npm install.npm run build to generate your minified file.Would you like me to help you write a sample GitHub Action script so that this library is automatically tested and obfuscated every time you push code to your repository?