@pigmilcom/a11y 1.1.0 → 1.1.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 CHANGED
@@ -78,11 +78,12 @@ A "request" is one widget initialisation (page load / route change).
78
78
 
79
79
  1. On widget mount the browser makes a single `GET` request to the PIGMIL API.
80
80
  2. The API checks whether the domain is registered and within quota.
81
- 3. The response (`valid`, `blocked`, or error) controls whether the widget renders:
81
+ 3. The response controls whether the widget renders:
82
82
  - **`valid`** — widget renders normally.
83
83
  - **`blocked`** — quota exceeded; widget does not render until the day / month resets or the plan is upgraded.
84
84
  - **`error`** / API unreachable — widget does not render (fail-closed on non-local domains).
85
85
  4. The result is cached in `sessionStorage` for 30 minutes to avoid redundant calls.
86
+ 5. Cached and returned result objects are `Object.freeze()`d — their `status` and `plan` properties cannot be mutated after resolution.
86
87
 
87
88
  ### Local / development environments
88
89
 
@@ -92,9 +93,19 @@ Validation is **automatically skipped** when the page runs on:
92
93
 
93
94
  The widget always renders in these environments with a free-plan appearance. No API key or sign-up is required during development.
94
95
 
96
+ ### Security layers
97
+
98
+ | Layer | What it does |
99
+ |---|---|
100
+ | **Server-side enforcement** (primary) | The PIGMIL API only validates registered domains, increments per-domain counters, and returns `blocked:true` when quotas are exceeded. This is the real gate — no client-side bypass can defeat it. |
101
+ | **Frozen result objects** | `Object.freeze()` on the validation result prevents callers from mutating `{ status, plan }` to escalate their own access level. |
102
+ | **CDN bundle obfuscation** | `dist/a11y.cdn.js` is post-processed by `javascript-obfuscator` with Base64 string-array encoding and self-defending code. The self-defending wrapper causes the bundle to break at runtime if it has been reformatted / prettified before execution, deterring the "prettify → grep → patch → re-minify" bypass workflow. The npm package source remains intentionally readable (open source). |
103
+ | **XOR-encoded endpoint** | The API URL is stored as a numeric XOR array in source and decoded at runtime, making it non-trivial to locate in the minified + obfuscated CDN bundle. |
104
+ | **Daily-rotating request signature** | Each API call includes an FNV-1a hash of `domain + YYYY-MM-DD` — a per-domain-per-day token the server can optionally verify to detect replayed or forged requests. |
105
+
95
106
  ### Current status (mock mode)
96
107
 
97
- The API endpoint is being implemented in the PIGMIL backend. Until it is live, `src/license.js` uses a **mock response** that always returns `{ ok: true, plan: 'free', blocked: false }`. To switch to the real API, remove the `_mock` block and uncomment the `fetch` block in that file.
108
+ The API endpoint is being implemented in the PIGMIL backend. Until it is live, `src/license.js` uses `MOCK_MODE = true`, which always returns `{ ok: true, plan: 'free', blocked: false }`. To switch to the real API, set `MOCK_MODE = false` in that file the fetch code is already written and ready.
98
109
 
99
110
  ---
100
111