@intellifend/requestshieldjs 2.0.0-qat.197

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/LICENSE.txt ADDED
@@ -0,0 +1,116 @@
1
+ REQUESTSHIELD JAVASCRIPT SDK LICENSE
2
+ Version 1.0 - 2026-09-22
3
+
4
+ Copyright (c) 2026 Request Shield. All rights reserved.
5
+
6
+ 1. Scope and ownership
7
+
8
+ This license applies to the proprietary portions of the RequestShield Browser
9
+ SDK, intended for distribution as @intellifend/requestshieldjs, including its
10
+ JavaScript bundles, embedded WebAssembly, type declarations, and accompanying
11
+ documentation (the "Software"). Request Shield, the legal entity
12
+ providing IntelliFend RequestShield, is the "Licensor". "You" means the person
13
+ or organization exercising the permissions below.
14
+
15
+ Licensor and its licensors retain ownership of the Software. Public access to
16
+ the Software through npm or a CDN does not make the proprietary portions open
17
+ source. Third-party components are governed by section 5.
18
+
19
+ 2. Permitted use and delivery
20
+
21
+ Subject to this license, Licensor grants You a worldwide, non-exclusive,
22
+ royalty-free license to:
23
+
24
+ (a) download, install, copy, and execute the Software to develop, test, and
25
+ operate websites and applications that integrate, or are being developed to
26
+ integrate, with IntelliFend RequestShield services You are authorized to use;
27
+
28
+ (b) configure the Software through its documented interfaces, and bundle,
29
+ minify, transpile, compress, or otherwise transform it as reasonably necessary
30
+ for that integration, without changing its protection or verification logic;
31
+
32
+ (c) host and deliver those copies with Your applications, including through
33
+ Your servers, hosting providers, package caches, and CDNs, and permit Your
34
+ application users and visitors to download, cache, and execute them as part
35
+ of using those applications; and
36
+
37
+ (d) allow Your contractors and service providers to perform these activities
38
+ on Your behalf, subject to the same limits.
39
+
40
+ Package registries, package managers, mirrors, and CDNs may copy, cache, and
41
+ serve unmodified releases solely to facilitate the permitted uses above and
42
+ must make this license and the applicable third-party notices available with
43
+ those releases. Your applications may be commercial or non-commercial. No
44
+ separate royalty is charged for the SDK permissions in this section.
45
+
46
+ 3. Conditions and limits
47
+
48
+ You must retain copyright, license, and attribution notices in distributed
49
+ copies. If a build process removes comments, preserve the notices in an
50
+ accompanying license or notices file and make that file available with the
51
+ delivered application or SDK assets.
52
+
53
+ Except for the delivery expressly permitted in section 2, You may not sell,
54
+ license, or republish the Software as a standalone SDK or library, claim it
55
+ as Your own, or use its proprietary code to offer a competing SDK or service.
56
+ You may not modify the proprietary Software beyond the integration
57
+ transformations permitted above without Licensor's written permission.
58
+
59
+ These limits do not restrict Your independently developed application code,
60
+ rights granted by a third-party license, or rights that applicable law does
61
+ not permit Licensor to restrict. No trademark rights are granted except to
62
+ identify the Software accurately and preserve required notices.
63
+
64
+ 4. Service access is separate
65
+
66
+ This license grants permission to use and deliver the SDK. It does not grant
67
+ an account, credentials, service capacity, support commitment, or a service
68
+ level agreement. Access to IntelliFend services, including any free or paid
69
+ plan, remains subject to the applicable service agreement and usage terms.
70
+ The free SDK license does not waive service charges or usage limits.
71
+
72
+ This license does not itself obtain consent for processing personal data or
73
+ replace applicable privacy terms, notices, or data-processing agreements.
74
+
75
+ 5. Third-party components
76
+
77
+ Third-party components retain their own copyright and license terms, as
78
+ identified in THIRD_PARTY_NOTICES.txt. Those terms govern the respective
79
+ components and take precedence over any conflicting restriction here.
80
+ Nothing in this license reduces permissions or obligations under those
81
+ third-party licenses or claims ownership of third-party code.
82
+
83
+ 6. Warranty and liability
84
+
85
+ Except as expressly agreed in writing and to the maximum extent permitted
86
+ by applicable law, the Software is provided "AS IS" and "AS AVAILABLE",
87
+ without warranties of merchantability, fitness for a particular purpose,
88
+ non-infringement, uninterrupted operation, or error-free operation. The SDK
89
+ does not guarantee that every automated or malicious request will be
90
+ detected or blocked.
91
+
92
+ To the maximum extent permitted by applicable law, Licensor is not liable
93
+ for indirect, incidental, special, exemplary, or consequential damages, or
94
+ loss of profits, revenue, data, or business opportunity arising from use of
95
+ the Software. Nothing here excludes liability that cannot lawfully be
96
+ excluded or overrides an express warranty or liability provision in an
97
+ applicable written agreement with Licensor.
98
+
99
+ 7. Termination
100
+
101
+ Licensor may terminate the permissions granted here if You materially breach
102
+ this license and do not remedy the breach within 30 days after written
103
+ notice. On termination, stop using and distributing the proprietary Software
104
+ and remove copies under Your control, except copies required by law or kept
105
+ solely in non-operational archives. You are not required to retrieve copies
106
+ already cached on visitors' devices. Termination does not terminate rights
107
+ granted independently by third-party licenses.
108
+
109
+ 8. Other agreements and reserved rights
110
+
111
+ If an applicable written agreement with Licensor expressly addresses SDK
112
+ licensing and conflicts with this license, that agreement controls the
113
+ proprietary Software. Third-party terms continue to control their respective
114
+ components. Rights not expressly granted are reserved. Distribution of a
115
+ later SDK version does not retroactively change the terms accompanying an
116
+ earlier version.
package/README.md ADDED
@@ -0,0 +1,264 @@
1
+ # RequestShield Browser SDK
2
+
3
+ The RequestShield Browser SDK obtains single-use proof-of-work tokens and either attaches them automatically to configured Fetch and asynchronous XHR requests or returns them for application-controlled transport. The customer backend remains the authority that verifies a token and decides how to handle a missing token.
4
+
5
+ ## Install
6
+
7
+ ### npm / ESM
8
+
9
+ Install the production release:
10
+
11
+ ```console
12
+ npm install @intellifend/requestshieldjs
13
+ ```
14
+
15
+ For testing, select the appropriate public prerelease channel:
16
+
17
+ | Environment | Installation | `challengeUrl` |
18
+ | --- | --- | --- |
19
+ | QAT | `npm install @intellifend/requestshieldjs@qat` | `https://challenge-dev.intellifend.ai` |
20
+ | STG | `npm install @intellifend/requestshieldjs@stg` | `https://challenge-stg.intellifend.ai` |
21
+ | Production | `npm install @intellifend/requestshieldjs` | `https://challenge.intellifend.ai` |
22
+
23
+ Import the API and initialize it with your environment's app key and Challenge
24
+ Server URL. This example targets QAT:
25
+
26
+ ```javascript
27
+ import { IntelliFend } from "@intellifend/requestshieldjs";
28
+
29
+ IntelliFend.init({
30
+ appKey: "YOUR_QAT_APP_KEY",
31
+ challengeUrl: "https://challenge-dev.intellifend.ai",
32
+ protect: ["/api/register"],
33
+ });
34
+ ```
35
+
36
+ The `qat` and `stg` tags select prerelease packages; they do not configure service URLs.
37
+ An installation without a tag selects the production `latest` release.
38
+ Without `challengeUrl`, the SDK uses `https://challenge.intellifend.ai`. Use the
39
+ app key and endpoint supplied for your environment. Pin the resolved version
40
+ in your application's lockfile for reproducible installations.
41
+
42
+ The ESM entry point exports `IntelliFend`, `IntelliFendError`, `VERSION`, and
43
+ TypeScript types. It does not attach a global or initialize itself. Use it in
44
+ browser applications with an ESM-capable toolchain.
45
+
46
+ ### Script tag
47
+
48
+ You can also serve the packaged `dist/intellifend.js` file from your own static
49
+ host, together with the license and third-party notices. For example:
50
+
51
+ ```html
52
+ <script
53
+ src="/vendor/requestshield/intellifend.js"
54
+ integrity="sha384-<digest-from-checksums.json>"
55
+ crossorigin="anonymous"
56
+ data-app-key="YOUR_QAT_APP_KEY"
57
+ data-challenge-url="https://challenge-dev.intellifend.ai"
58
+ data-protect='["/api/register"]'
59
+ defer>
60
+ </script>
61
+ ```
62
+
63
+ Use the digest for `intellifend.js` from the packaged `dist/checksums.json`.
64
+ The script-tag build creates the `IntelliFend` global and initializes it from
65
+ script attributes. It never overwrites an existing `IntelliFend` global.
66
+ For an IntelliFend-hosted script, use the immutable URL and matching integrity
67
+ digest supplied for your SDK release.
68
+
69
+ ### WebAssembly requirement
70
+
71
+ Version 2.0 requires WebAssembly, including when optional collection is disabled.
72
+ The module is embedded in the SDK bundle; it adds no separate module URL or
73
+ download. Pages enforcing CSP must allow `'wasm-unsafe-eval'` in `script-src`.
74
+ Existing script, service, and Web Worker permissions remain necessary.
75
+
76
+ `init()` remains synchronous. Token acquisition waits for module readiness
77
+ within the existing whole-flow deadline. If WebAssembly is unavailable, blocked,
78
+ or fails, `getToken()` resolves to `""`. Seamless mode sends the application
79
+ request without adding a token, and the backend applies its missing-token
80
+ policy. Test this path together with your CSP and browser requirements.
81
+
82
+ ## Quick start
83
+
84
+ ### Seamless mode
85
+
86
+ Pass the application endpoints that should receive a token in `protect`, as in
87
+ the initialization example above. To protect endpoints on another origin,
88
+ include their absolute HTTPS URLs:
89
+
90
+ ```javascript
91
+ IntelliFend.init({
92
+ appKey: "YOUR_QAT_APP_KEY",
93
+ challengeUrl: "https://challenge-dev.intellifend.ai",
94
+ protect: ["/api/register", "https://api.example.com/login"],
95
+ });
96
+ ```
97
+
98
+ The SDK adds `X-IntelliFend-Token` to matching Fetch and asynchronous XHR requests
99
+ when it obtains a non-empty token. Protect the corresponding business mutation
100
+ on the backend; browser matching and token attachment are not authorization
101
+ controls.
102
+
103
+ ### Manual mode
104
+
105
+ Obtain a token immediately before the protected request and carry it unchanged. The header is the recommended carrier:
106
+
107
+ ```javascript
108
+ const token = await IntelliFend.getToken({ action: "register" });
109
+ const headers = new Headers({ "Content-Type": "application/json" });
110
+
111
+ if (token) {
112
+ headers.set("X-IntelliFend-Token", token);
113
+ }
114
+
115
+ await fetch("/api/register", {
116
+ method: "POST",
117
+ headers,
118
+ body: JSON.stringify(formData),
119
+ });
120
+ ```
121
+
122
+ `getToken()` returns `""` when it cannot obtain a token and never rejects. Continue the application request so the backend can apply its configured missing-token or availability policy.
123
+
124
+ ## Configuration and API reference
125
+
126
+ ### `IntelliFend.init(config)`
127
+
128
+ | Option | Required | Description |
129
+ | --- | --- | --- |
130
+ | `appKey` | Yes | Public app key supplied by IntelliFend. |
131
+ | `challengeUrl` | No | Absolute Challenge Server base URL. Defaults to `https://challenge.intellifend.ai`. It must use HTTP(S) and contain no credentials, query, or fragment. |
132
+ | `fallbackChallengeUrl` | No | Approved absolute HTTPS secondary base URL, without credentials, query, or fragment. Omitted by default. An identical normalized primary URL adds no alternate endpoint. |
133
+ | `timeoutMs` | No | Positive whole-flow time budget for create, solve, verify, and retries. Defaults to 5,000 ms. |
134
+ | `protect` | No | Exact endpoint path or URL strings for Seamless mode. Omit or pass an empty list for Manual-only operation. |
135
+ | `telemetry` | No | Enables the optional browser signal collection described below. Default `false`. |
136
+
137
+ `init()` validates synchronously and throws `IntelliFendError` with code `invalid_config` for invalid input. Reinitialization replaces the previous valid configuration; a failing reinitialization leaves that configuration in place. Unknown configuration keys are ignored.
138
+
139
+ Script-tag integrations use the equivalent attributes `data-app-key`, `data-challenge-url`, `data-protect`, and `data-fallback-challenge-url`. `data-protect` must be a JSON array of strings. The collector accepts only the exact `data-telemetry="true"` and `data-telemetry="false"` values; invalid supplied values use the same sanitized `invalid_config` auto-init warning.
140
+
141
+ ### Optional secondary domain
142
+
143
+ Use the endpoint pair supplied by IntelliFend with a compatible approved bundle and service configuration:
144
+
145
+ ```javascript
146
+ IntelliFend.init({
147
+ appKey: "YOUR_APP_KEY",
148
+ challengeUrl: "https://challenge.example.com",
149
+ fallbackChallengeUrl: "https://challenge-alt.example.com",
150
+ });
151
+ ```
152
+
153
+ URLs are normalized for surrounding whitespace and trailing slashes while retaining path prefixes. No secondary hostname is inferred automatically. A missing or identical fallback preserves the existing single-endpoint behavior.
154
+
155
+ With a distinct fallback, each create or verify operation still gets at most two attempts. Its first network attempt, including the response-body read, has at most `min(1000 ms, remaining flow budget / 2)`. An eligible failure tries the other endpoint after bounded retry jitter if enough time remains. The second attempt uses the remaining budget. The configured whole-flow deadline includes create, solve, verify, and retries; it defaults to 5,000 ms and never resets on a switch.
156
+
157
+ Eligible failures are network rejection, individual attempt timeout, HTTP 5xx, interrupted successful response-body reads, and non-binary HTTP 2xx proxy responses. Received 4xx, fully read malformed binary, invalid challenge scope/shape, solver failure, cancellation, and whole-flow expiry stop acquisition. Verify starts on the endpoint that supplied the validated challenge; a verify retry reuses that challenge and solution without repeating PoW.
158
+
159
+ Successful token acquisition through secondary establishes a fixed 60-second preference in page memory. Further secondary successes, including overlapping fallback flows, do not extend an active window. After expiry the next flow tries primary; recovery clears the preference. Reinitialization resets it. Among overlapping successful flows, the later-started flow determines preference; a late completion from an older flow cannot replace it. No cookies, browser storage, or health-polling requests are used. Both endpoints bypass Seamless interception and preserve omitted credentials and header-free challenge requests. `getToken()` still returns a token or `""`.
160
+
161
+ ### Optional browser signal collection
162
+
163
+ `telemetry: true` collects a bounded summary of browser
164
+ interaction and timezone information in page memory for up to five minutes.
165
+ Each token flow samples the current numeric timezone offset and sends one
166
+ snapshot with the challenge request. The optional timezone name is resolved
167
+ during idle work and may reflect an earlier timezone setting.
168
+
169
+ The collector does not retain raw events, typed text, key values, DOM references,
170
+ or mouse paths. It uses no cookies, browser storage, or persistent identity and
171
+ sends no separate telemetry request. Collection is disabled by default, and a
172
+ collection failure does not fail token acquisition.
173
+
174
+ ### `IntelliFend.getToken(options?)`
175
+
176
+ | Option | Description |
177
+ | --- | --- |
178
+ | `action` | Optional non-empty, case-sensitive action carried in the signed token. It is not an authorization decision by itself; compare it only with trusted backend configuration after normal token verification succeeds. |
179
+ | `timeoutMs` | Optional per-call timeout. It may narrow, but never widen, the timeout set by `init()`. |
180
+ | `signal` | Optional `AbortSignal` that cancels the complete token flow. |
181
+
182
+ The method always resolves to a string: the issued token or `""` for validation, cancellation, timeout, transport, service, response, or solver failure.
183
+
184
+ ### Endpoint matching
185
+
186
+ - A root-relative entry is resolved once against the current page origin.
187
+ - An absolute entry must not contain credentials. Cross-origin entries require HTTPS, except for `localhost`, `127.0.0.1`, and `[::1]`; same-origin HTTP is allowed.
188
+ - Query strings and fragments are ignored. Origin and pathname must otherwise match exactly, including case and trailing slash.
189
+ - Relative application URLs use `document.baseURI` at the native call boundary: Fetch captures it when `fetch()` is called, and XHR captures it when `open()` is called. A later `<base>` change cannot retarget a delayed protected request.
190
+ - Rules apply to every HTTP method.
191
+ - Seamless mode covers Fetch and asynchronous XHR. It does not cover synchronous XHR, native form navigation, `sendBeacon`, WebSocket, EventSource, service-worker-owned traffic, or transports cached before SDK initialization.
192
+ - Fetch requests whose effective mode is `no-cors` are sent unchanged because JavaScript cannot add the token header.
193
+
194
+ ## Integration behavior
195
+
196
+ ### Fail-through and header precedence
197
+
198
+ If token acquisition, endpoint matching, interception, or header preparation fails, the SDK sends the original application request once without adding a token. A protected Fetch call is snapshotted synchronously, so mutating its URL, options, headers, or body after `fetch()` returns does not change a delayed dispatch. A pre-existing non-empty `X-IntelliFend-Token` value always wins and suppresses automatic token acquisition. This browser fail-through is not an allow decision; the backend owns missing-token policy and verification.
199
+
200
+ Protected asynchronous XHR also captures its body when `send()` is called.
201
+ Later edits to URLSearchParams, FormData, ArrayBuffer/view bytes, or a Document
202
+ do not change the delayed request. Native XHR retains responsibility for body
203
+ serialization, file names, MIME types, and document charset handling. GET/HEAD
204
+ bodies remain ignored. If capture fails, the original native `send()` runs
205
+ immediately with the original body and retains its native validation errors.
206
+
207
+ Challenge hostname validation uses the server's canonical DNS spelling,
208
+ including removal of one terminal root dot. This does not change exact-origin
209
+ Seamless endpoint matching.
210
+
211
+ ### Token lifetime and single use
212
+
213
+ Tokens are short-lived and single-use. Use one token for one protected application request, obtain a fresh token for a retry, and never reuse a token after native Fetch or XHR dispatch may have sent it. Seamless mode manages one warm token and never gives the same token to two requests.
214
+
215
+ ### CORS
216
+
217
+ For a cross-origin protected application API, allow the `X-IntelliFend-Token` request header in that API's CORS policy. This is separate from the Challenge Server connection.
218
+
219
+ ### Manual transport
220
+
221
+ `X-IntelliFend-Token` is the recommended Manual-mode carrier. A dedicated request-body or form field is also valid when the backend extracts it before verification. Never place a token in a URL path, query string, or fragment because those locations are commonly logged and cached.
222
+
223
+ ### Challenge Server proxies
224
+
225
+ A Challenge Server proxy must forward binary request and response bodies unchanged, accept `POST` requests with no request `Content-Type`, and preserve the browser `Origin`. Do not parse or reserialize the bodies as JSON. Challenge create and verify requests deliberately set no author headers so their normal cross-origin POSTs remain CORS simple requests without an OPTIONS preflight.
226
+
227
+ ### CSP
228
+
229
+ For 2.0, pages with Content Security Policy need `'wasm-unsafe-eval'` in
230
+ `script-src` alongside the approved script origin, `connect-src` permission for
231
+ both configured Challenge Server origins, and `worker-src blob:` for the
232
+ proof-of-work Web Worker. Keep JavaScript evaluation blocked; broad
233
+ `'unsafe-eval'` is unnecessary. Configure the secondary URL as HTTPS directly;
234
+ an HTTP redirect is insufficient on an HTTPS page.
235
+
236
+ ### Subresource Integrity
237
+
238
+ Pin an immutable `requestshield/v<version>/intellifend.js` URL, use the matching `sha384-...` value from that release's `checksums.json`, and set `crossorigin="anonymous"`. Do not combine a fixed integrity value with `requestshield/latest/` or the mutable root alias. The static host must authorize the cross-origin script request through CORS.
239
+
240
+ ### Sensitive values
241
+
242
+ Do not log raw tokens or raw challenges. Redact the selected token carrier in proxies and application logs without changing the value sent for verification.
243
+
244
+ ## Browser compatibility and performance
245
+
246
+ The SDK targets Chrome/Edge 97+, Firefox 102+, and Safari/iOS 16+ with
247
+ WebAssembly and the required CSP permission. Test your integration on the
248
+ browsers and devices your application supports. Proof-of-work runs off the
249
+ main thread in a Web Worker.
250
+ Completion time depends on the device and service-selected challenge. Module
251
+ readiness shares the default five-second token budget; expiry returns `""`,
252
+ and the backend remains responsible for its missing-token policy.
253
+
254
+ ## License
255
+
256
+ The proprietary SDK is licensed by Request Shield under [LICENSE.txt](LICENSE.txt).
257
+ Integration with authorized IntelliFend services has no SDK royalty; service
258
+ access and charges remain separate. Public distribution does not make the SDK
259
+ open source. Preserve the license and [third-party notices](THIRD_PARTY_NOTICES.txt) when
260
+ bundling or redistributing it with your application.
261
+
262
+ ## Support
263
+
264
+ Contact IntelliFend support for an application key, the approved Challenge Server URL, an immutable bundle URL and SRI digest, or integration assistance. Include the SDK version and sanitized error context; never include tokens, challenges, or credentials.