StateGuard

🛡️ StateGuard.js

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.

🚀 Key Features


Core Concepts

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.

Installation

CDN

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>

NPM

Install the package via npm:

npm install @rsuthar/state-guard-js

Yarn

yarn add @rsuthar/state-guard-js

PNPM

pnpm add @rsuthar/state-guard-js

API Reference

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

🛠️ Integration Guide

Vanilla JavaScript

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';
            }
        });
    }
});

React (Using Hooks)

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'));
};

Angular (Using Directives)

Apply protection declaratively in your templates.

<button appStateGuard [protectedAttributes]="['disabled']" (violation)="logIt($event)">
  Secure Action
</button>


🔒 Security Hardening Tips

  1. Run the Obfuscator: Always run npm run obfuscate before deploying. This makes it incredibly difficult for attackers to find the “unlock” logic in your source code.
  2. The Debugger Loop: Our production build includes a self-defending loop that triggers a debugger statement if DevTools are opened while the script is running.
  3. Backend Verification:
    • Level 1: StateGuard prevents the button from being enabled.
    • Level 2: Your server verifies if the user actually has the permissions to perform the action associated with that button. Never trust the client alone.

🧪 Testing the Guard

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.


Release Notes

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.

Next Steps for You

  1. Initialize the project: Run npm init -y in your folder and paste the package.json content.
  2. Install dependencies: Run npm install.
  3. Build: Run 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?