siarashield_workspace 0.0.33 → 0.0.35

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
@@ -1,49 +1,31 @@
1
- ## `siarashield_workspace`
1
+ # `siarashield_workspace`
2
2
 
3
3
  Angular integration for CyberSiara **SiaraShield** captcha.
4
4
 
5
5
  ## Angular compatibility
6
6
 
7
- - Minimum supported Angular version: `16`
8
- - Supported Angular range: `16.x` to `21.x`
9
- - Peer dependency in package is set to:
7
+ - Minimum supported Angular: `16`
8
+ - Supported range: `16.x` to `21.x`
9
+ - Peer dependencies:
10
10
  - `@angular/core >=16.0.0 <22.0.0`
11
11
  - `@angular/common >=16.0.0 <22.0.0`
12
12
 
13
- ## Install
13
+ ## Quick start (recommended, easiest path)
14
+
15
+ Use this flow first. Most users need only these steps.
16
+
17
+ 1. Install package:
14
18
 
15
19
  ```bash
16
20
  npm i siarashield_workspace
17
21
  ```
18
22
 
19
- ## Quick setup (clear path)
20
-
21
- Choose one integration style only:
22
-
23
- - **Recommended:** Angular component (`<siara-shield ...>`).
24
- - **Alternative:** function API (`initSiaraShield(...)` + `checkSiaraShieldCaptcha...`).
25
-
26
- Do not mix both styles on the same page.
27
-
28
- 1. Install package: `npm i siarashield_workspace`.
29
- 2. Put only the **public key** in Angular environment.
30
- 3. Keep the **private key** on backend only (`.env` or secret store).
31
- 4. Render captcha container (component tag or `<div class="SiaraShield"></div>` for function API).
32
- 5. Keep submit button class: `class="CaptchaSubmit"`.
33
- 6. Initialize captcha once per page load.
34
- 7. On submit, run captcha check before API call.
35
- 8. Call API only when captcha returns success (`result.ok === true` or `ok === true`).
36
-
37
- ## Get your keys
38
-
39
- Get your public and private keys from <a href="https://mycybersiara.com" target="_blank" rel="noopener noreferrer">mycybersiara.com</a>.
40
-
41
- ## Put keys in the right place
23
+ 2. Ensure Angular environment files exist.
24
+ - If your project does not have `src/environments`, create:
25
+ - `src/environments/environment.ts`
26
+ - `src/environments/environment.prod.ts`
42
27
 
43
- - **Frontend (Angular):** public key only
44
- - **Backend (.env):** private key only
45
-
46
- Angular `environment` example:
28
+ 3. Put only your **public key** in Angular environment:
47
29
 
48
30
  ```ts
49
31
  export const environment = {
@@ -51,17 +33,7 @@ export const environment = {
51
33
  };
52
34
  ```
53
35
 
54
- Backend `.env` example:
55
-
56
- ```dotenv
57
- SIARASHIELD_PRIVATE_KEY=YOUR-PRIVATE-KEY
58
- ```
59
-
60
- Never place the private key in Angular environment files, templates, or browser code.
61
-
62
- ## Recommended: use the Angular component (easiest)
63
-
64
- ### 1) Add the component to your template
36
+ 4. Render component + submit button in template:
65
37
 
66
38
  ```html
67
39
  <siara-shield
@@ -73,7 +45,7 @@ Never place the private key in Angular environment files, templates, or browser
73
45
  <button type="submit" class="CaptchaSubmit" (click)="onSubmit()">Submit</button>
74
46
  ```
75
47
 
76
- ### 2) Copy-paste TypeScript
48
+ 5. Check captcha before API submit:
77
49
 
78
50
  ```ts
79
51
  import { Component, ViewChild } from '@angular/core';
@@ -88,63 +60,76 @@ import { SiaraShieldComponent } from 'siarashield_workspace';
88
60
  })
89
61
  export class FormComponent {
90
62
  protected readonly environment = environment;
91
-
92
- // Recommended: set from server (see CSP section)
93
63
  protected readonly cspNonce = (window as any).__cspNonce as string | undefined;
94
- private isSubmitting = false;
95
64
 
65
+ private isSubmitting = false;
96
66
  @ViewChild(SiaraShieldComponent) private readonly captcha?: SiaraShieldComponent;
97
67
 
98
68
  onCaptchaToken(token: string) {
99
- // Optional: use token immediately if needed
100
69
  console.log('SiaraShield token:', token);
101
70
  }
102
71
 
103
72
  async onSubmit() {
104
73
  if (this.isSubmitting) return;
105
74
  this.isSubmitting = true;
106
-
107
75
  try {
108
76
  const ok = await this.captcha?.checkCaptchaAsync();
109
- if (!ok) {
110
- console.log('Captcha not completed yet');
111
- return;
112
- }
77
+ if (!ok) return;
113
78
 
114
- // When ok=true, token is available in global state and from (token) output.
79
+ // Call your backend API only after captcha success.
115
80
  alert('Form submitted successfully');
116
81
  } finally {
117
- // Allow next user attempt if captcha or API flow was not completed.
118
82
  this.isSubmitting = false;
119
83
  }
120
84
  }
121
85
  }
122
86
  ```
123
87
 
124
- Notes:
88
+ 6. Keep your submit API logic only in the success branch (`ok === true`).
89
+
90
+ ## Key handling (required)
91
+
92
+ - **Frontend (Angular): public key only**
93
+ - **Backend (.env or secret store): private key only**
125
94
 
126
- - If you already load jQuery in your app, set `[loadJQuery]="false"` on the component.
127
- - Keep `class="CaptchaSubmit"` on your submit button (required by vendor flow).
128
- - The component renders the required captcha container (`<div class="SiaraShield"></div>`) internally at that position in the template.
129
- - Vendor debug logs are suppressed by default. Set `[allowVendorConsoleLogs]="true"` only while debugging.
95
+ Backend example:
96
+
97
+ ```dotenv
98
+ SIARASHIELD_PRIVATE_KEY=YOUR-PRIVATE-KEY
99
+ ```
130
100
 
131
- ## Alternative: function API (when you cannot use the component)
101
+ Never place the private key in Angular code or browser-accessible files.
132
102
 
133
- Template for function API:
103
+ Get keys from [mycybersiara.com](https://mycybersiara.com).
104
+
105
+ ## Integration rules (important)
106
+
107
+ - Choose one style per page:
108
+ - **Recommended:** `<siara-shield ...>`
109
+ - **Alternative:** function API
110
+ - Do not mix both styles on the same page.
111
+ - Keep submit button class: `CaptchaSubmit`.
112
+ - Initialize captcha once per page load.
113
+
114
+ ## Function API (alternative)
115
+
116
+ Use this only when component integration is not possible.
117
+
118
+ Template:
134
119
 
135
120
  ```html
136
121
  <div class="SiaraShield"></div>
137
122
  <button type="submit" class="CaptchaSubmit" (click)="onSubmit()">Submit</button>
138
123
  ```
139
124
 
125
+ TypeScript:
126
+
140
127
  ```ts
141
128
  import { environment } from '../environments/environment';
142
129
  import { initSiaraShield, checkSiaraShieldCaptcha } from 'siarashield_workspace';
143
130
 
144
131
  export class FormComponent {
145
132
  ngOnInit() {
146
- // Angular does not wait for async lifecycle hooks.
147
- // Use void to run async init without blocking render.
148
133
  void this.initializeCaptcha();
149
134
  }
150
135
 
@@ -152,68 +137,47 @@ export class FormComponent {
152
137
  await initSiaraShield({
153
138
  publicKey: environment.siaraShieldPublicKey,
154
139
  cspNonce: (window as any).__cspNonce || undefined,
155
- // Optional: set true only while debugging vendor/runtime internals.
156
- allowVendorConsoleLogs: false,
157
140
  });
158
141
  }
159
142
 
160
143
  onSubmit() {
161
144
  const result = checkSiaraShieldCaptcha();
162
- if (!result.ok) {
163
- console.log('Captcha not completed yet');
164
- return;
165
- }
145
+ if (!result.ok) return;
166
146
 
167
147
  console.log(result.token);
168
148
  // API call here
169
- alert('Form submitted successfully');
170
149
  }
171
150
  }
172
151
  ```
173
152
 
174
- Keep submit API logic inside the successful captcha branch.
175
-
176
- If your frontend reads nonce from the DOM instead of `window`, reuse nonce from an existing script tag:
177
-
178
- ```ts
179
- const nonce = document.querySelector('script[nonce]')?.getAttribute('nonce') || undefined;
180
- ```
181
-
182
- The nonce must be generated on the server for each request. The package NEVER generates a nonce in the browser.
183
-
184
- ## CSP Compliance (Important)
153
+ ## CSP guide
185
154
 
186
- Inline scripts are blocked by CSP unless you allow them with a nonce or a hash. This package does not execute inline JavaScript and does not use `eval()`, `new Function()`, `setTimeout(string)`, `setInterval(string)`, or any other string-based execution path. All scripts are loaded as external resources. Any dynamically created `<script>` elements are assigned the provided CSP nonce when `cspNonce` is passed.
155
+ If your app has no strict CSP, default integration works without extra setup.
187
156
 
188
- For strict CSP deployments:
157
+ If your app uses strict nonce-based CSP:
189
158
 
190
- - Generate the nonce on the server for each request.
191
- - Use the same nonce in the `Content-Security-Policy` header.
192
- - Use the same nonce on the `<script>` tag that loads your Angular app or any direct SiaraShield resource.
193
- - Use the same nonce in `initSiaraShield({ cspNonce: ... })`.
194
- - The package NEVER generates a nonce in the browser.
195
- - If a valid CSP nonce is required but not provided, browsers will block script execution and the captcha will fail to load.
159
+ - Generate nonce on server for each request.
160
+ - Use same nonce in:
161
+ - `Content-Security-Policy` header
162
+ - script tags loading your Angular app
163
+ - `cspNonce` option/input
164
+ - Do not generate nonce in browser.
196
165
 
197
- ### Production copy-paste policy (recommended for easiest client integration)
166
+ ### Strict policy example (recommended for security)
198
167
 
199
- Use this when you want a client-safe setup that avoids popup close issues with current vendor runtime.
200
-
201
- ```html
202
- <meta http-equiv="Content-Security-Policy" content="
203
- default-src 'self';
204
- script-src 'self' 'unsafe-inline' https://embed.mycybersiara.com https://embedcdn.mycybersiara.com;
205
- script-src-elem 'self' 'unsafe-inline' https://embed.mycybersiara.com https://embedcdn.mycybersiara.com;
206
- connect-src 'self' https://embed.mycybersiara.com https://embedcdn.mycybersiara.com;
207
- style-src 'self' https://embed.mycybersiara.com https://mycybersiara.com https://fonts.googleapis.com https://cdnjs.cloudflare.com 'unsafe-inline';
208
- font-src 'self' https://fonts.gstatic.com https://mycybersiara.com https://cdnjs.cloudflare.com data:;
209
- img-src 'self' data: https://embed.mycybersiara.com https://embedcdn.mycybersiara.com https://mycybersiara.com;
210
- ">
211
-
212
- <script nonce="SIARASHIELD_NONCE" src="https://embedcdn.mycybersiara.com/capcha-temple/js/jquery.min.js"></script>
213
- <script nonce="SIARASHIELD_NONCE" src="https://embedcdn.mycybersiara.com/CaptchaFormate/CaptchaResources.js"></script>
168
+ ```http
169
+ default-src 'self';
170
+ script-src 'self' 'nonce-<dynamic>' https://embed.mycybersiara.com https://embedcdn.mycybersiara.com;
171
+ script-src-elem 'self' 'nonce-<dynamic>' https://embed.mycybersiara.com https://embedcdn.mycybersiara.com;
172
+ connect-src 'self' https://embed.mycybersiara.com https://embedcdn.mycybersiara.com;
173
+ style-src 'self' https://embed.mycybersiara.com https://mycybersiara.com https://fonts.googleapis.com https://cdnjs.cloudflare.com;
174
+ font-src 'self' https://fonts.gstatic.com https://mycybersiara.com https://cdnjs.cloudflare.com data:;
175
+ img-src 'self' data: https://embed.mycybersiara.com https://embedcdn.mycybersiara.com https://mycybersiara.com;
214
176
  ```
215
177
 
216
- If your backend uses helper functions, generate compatibility policy like this:
178
+ ### Compatibility policy (easier integration, weaker security)
179
+
180
+ Use only when customer policy allows `'unsafe-inline'`:
217
181
 
218
182
  ```ts
219
183
  import { getSiaraShieldCspPolicy } from 'siarashield_workspace';
@@ -224,107 +188,53 @@ const csp = getSiaraShieldCspPolicy({
224
188
  });
225
189
  ```
226
190
 
227
- ### Strict copy-paste quick test (advanced, static nonce for local verification only)
191
+ ## Script loading behavior
228
192
 
229
- Use this only for local or staging validation. In production, replace `siarashield-example-nonce` with a server-generated nonce per request.
230
-
231
- ```html
232
- <script nonce="siarashield-example-nonce">
233
- window.__cspNonce = "siarashield-example-nonce";
234
- </script>
235
- <script nonce="siarashield-example-nonce" src="https://embedcdn.mycybersiara.com/capcha-temple/js/jquery.min.js"></script>
236
- <script nonce="siarashield-example-nonce" src="https://embedcdn.mycybersiara.com/CaptchaFormate/CaptchaResources.js"></script>
237
-
238
- <meta http-equiv="Content-Security-Policy" content="
239
- default-src 'self';
240
- script-src 'self' 'nonce-siarashield-example-nonce' https://embed.mycybersiara.com https://embedcdn.mycybersiara.com;
241
- script-src-elem 'self' 'nonce-siarashield-example-nonce' https://embed.mycybersiara.com https://embedcdn.mycybersiara.com;
242
- connect-src 'self' https://embed.mycybersiara.com https://embedcdn.mycybersiara.com;
243
- style-src 'self' https://embed.mycybersiara.com https://mycybersiara.com https://fonts.googleapis.com https://cdnjs.cloudflare.com 'unsafe-inline';
244
- font-src 'self' https://fonts.gstatic.com https://mycybersiara.com https://cdnjs.cloudflare.com data:;
245
- img-src 'self' data: https://embed.mycybersiara.com https://embedcdn.mycybersiara.com https://mycybersiara.com;
246
- ">
247
- ```
248
-
249
- ### Strict production CSP policy (advanced)
250
-
251
- In production, send CSP as an HTTP response header and inject the same nonce value into script tags and `initSiaraShield({ cspNonce })`.
252
-
253
- ```http
254
- default-src 'self';
255
- script-src 'self' 'nonce-<dynamic>' https://embed.mycybersiara.com https://embedcdn.mycybersiara.com;
256
- script-src-elem 'self' 'nonce-<dynamic>' https://embed.mycybersiara.com https://embedcdn.mycybersiara.com;
257
- connect-src 'self' https://embed.mycybersiara.com https://embedcdn.mycybersiara.com;
258
- style-src 'self' https://embed.mycybersiara.com https://mycybersiara.com https://fonts.googleapis.com https://cdnjs.cloudflare.com;
259
- font-src 'self' https://fonts.gstatic.com https://mycybersiara.com https://cdnjs.cloudflare.com data:;
260
- img-src 'self' data: https://embed.mycybersiara.com https://embedcdn.mycybersiara.com https://mycybersiara.com;
261
- ```
262
-
263
- Example with the same server-generated nonce in script tags:
264
-
265
- ```html
266
- <script nonce="SIARASHIELD_NONCE">
267
- window.__cspNonce = "SIARASHIELD_NONCE";
268
- </script>
269
- <script nonce="SIARASHIELD_NONCE" src="https://embedcdn.mycybersiara.com/capcha-temple/js/jquery.min.js"></script>
270
- <script nonce="SIARASHIELD_NONCE" src="https://embedcdn.mycybersiara.com/CaptchaFormate/CaptchaResources.js"></script>
271
- ```
193
+ By default (`loadJQuery: true`) package loads required vendor resources automatically:
272
194
 
273
- If your Angular app initializes SiaraShield from the main application bundle, that bundle `<script>` tag must use the same nonce as the CSP header.
195
+ - `https://embedcdn.mycybersiara.com/capcha-temple/js/jquery.min.js` (fallback when jQuery not already present)
196
+ - `https://embedcdn.mycybersiara.com/CaptchaFormate/CaptchaResources.js`
197
+ - `https://embed.mycybersiara.com/CaptchaFormate/SiaraShield_Validation.js`
274
198
 
275
- `getSiaraShieldCspPolicy()` and `mergeSiaraShieldCspPolicy()` only generate a baseline CSP string. These helpers do not inject a nonce and do not apply headers. The server must inject the nonce and must apply the final `Content-Security-Policy` header.
199
+ Most users should **not** add these script tags manually.
276
200
 
277
- Notes:
201
+ If your app already has jQuery, set `[loadJQuery]="false"` (or `loadJQuery: false` in function API).
278
202
 
279
- - CSP helpers default to strict policy (no `script-src 'unsafe-inline'`).
280
- - For easiest client integration, use the compatibility policy above (`includeUnsafeInlineScript: true`, `includeUnsafeInlineStyle: true`).
281
- - Generating a new nonce in the browser (or per function call) does not help. CSP nonce must match the value from server response headers for that page load.
203
+ ## Advanced validation options
282
204
 
283
- The package still works in environments without CSP or with relaxed policies. If your site uses a strict nonce-based CSP, passing the server-generated nonce is required.
205
+ `checkCaptchaAsync(...)` and `checkSiaraShieldCaptchaAsync(...)` support optional tuning:
284
206
 
285
- ## jQuery loading behavior
207
+ - `timeoutMs`
208
+ - `pollIntervalMs`
209
+ - `beforeCheckDelayMs`
210
+ - `retryOnFalseMs` (default `0`)
211
+ - `falseResultTokenWaitMs` (default `900`)
286
212
 
287
- - Default `loadJQuery` is `true`.
288
- - If jQuery is not already available, the package loads:
289
- - `https://embedcdn.mycybersiara.com/capcha-temple/js/jquery.min.js`
290
- - The package also loads:
291
- - `https://embedcdn.mycybersiara.com/CaptchaFormate/CaptchaResources.js`
292
- - `https://embed.mycybersiara.com/CaptchaFormate/SiaraShield_Validation.js`
293
- - jQuery and the captcha bootstrap process may create script elements dynamically (including via HTML strings / DOM fragments).
294
- - When `cspNonce` is provided, dynamically inserted `<script>` elements are assigned that nonce (including scripts inserted indirectly through DOM manipulation).
295
- - The plugin includes a built-in guard that blocks vendor synthetic clicks on `.CaptchaSubmit` and suppresses rapid duplicate user clicks.
296
- - No application code changes are required for this guard.
297
- - This is required for compatibility with strict nonce-based CSP policies.
298
- - If a valid CSP nonce is required but not passed, browsers will block those script loads and the captcha will fail to initialize.
299
- - If your app already loads jQuery, set `loadJQuery: false`.
300
- - If your app loads jQuery from another CDN, allow that host in `script-src` and `script-src-elem`.
213
+ Default behavior is tuned to avoid requiring a second user click when token arrives slightly after first response.
301
214
 
302
215
  ## Quick troubleshooting
303
216
 
304
217
  - Captcha not visible:
305
- - If you use `<siara-shield ...>`, confirm the component is rendered (no `*ngIf` hiding it) and the page has finished loading scripts.
306
- - If you use the function API, confirm your template contains `<div class="SiaraShield"></div>`.
307
- - Confirm your submit button has `class="CaptchaSubmit"`.
218
+ - Confirm component is rendered and not hidden.
219
+ - Confirm submit button has `class="CaptchaSubmit"`.
220
+ - For function API, confirm `<div class="SiaraShield"></div>` exists.
308
221
  - `CheckCaptcha` not available:
309
- - Ensure initialization completed (for the function API: `await initSiaraShield(...)`).
310
- - Ensure CSP allows the required hosts and the correct nonce is used.
311
- - CSP error in console:
312
- - Confirm the same **server-generated nonce** is present in CSP header, bootstrapping `<script>` tag, and initialization (`cspNonce`).
313
- - A CSP warning/error on captcha popup close can still appear with current upstream vendor runtime on strict policies; if captcha flow still works, this is non-blocking. Use the compatibility policy (`includeUnsafeInlineScript: true`) when customer policy allows it.
314
- - `Identifier 'currentLangCode' has already been declared`:
315
- - This is a known vendor duplicate-inline-script issue during re-entry/navigation.
316
- - The package now blocks duplicate insertion for that vendor snippet; upgrade to the latest build.
317
- - Token empty -> check browser console and network calls after clicking submit.
318
-
319
- ## Final checklist (customer handover)
320
-
321
- - Public key is in frontend; private key stays only on backend.
322
- - Submit button includes `class="CaptchaSubmit"`.
323
- - Captcha container exists (component tag or `<div class="SiaraShield"></div>` for function API).
324
- - Same nonce value is used in CSP header, script tags, and `initSiaraShield({ cspNonce })`.
325
- - Captcha check runs before API call.
326
-
327
- ## Build and pack (library maintainers)
222
+ - Ensure initialization completed.
223
+ - Ensure CSP allows required hosts and nonce.
224
+ - Token not available immediately:
225
+ - Use async check methods (`checkCaptchaAsync` / `checkSiaraShieldCaptchaAsync`).
226
+ - CSP errors:
227
+ - Confirm same server-generated nonce in header, script tags, and `cspNonce`.
228
+
229
+ ## Final checklist
230
+
231
+ - Public key in frontend, private key only in backend.
232
+ - Submit button contains `CaptchaSubmit`.
233
+ - Captcha check runs before submit API call.
234
+ - Only one integration style is used per page.
235
+ - CSP nonce is wired correctly for strict CSP deployments.
236
+
237
+ ## Build and pack (maintainers)
328
238
 
329
239
  ```bash
330
240
  npm run build:lib
@@ -0,0 +1,98 @@
1
+ import { getSiaraShieldGlobals } from './siara-shield.globals';
2
+ const VENDOR_RUNTIME_PATCH_KEY = '__siaraShieldVendorRuntimePatchInstalled__';
3
+ const VENDOR_TOKEN_BRIDGE_KEY = '__siaraShieldVendorTokenBridgeInstalled__';
4
+ const WRAPPED_FN_PREFIX = '__siaraShieldWrappedVendorFn__';
5
+ function isKnownVendorNullDomError(error) {
6
+ const msg = error instanceof Error ? error.message.toLowerCase() : String(error ?? '').toLowerCase();
7
+ return (msg.includes("cannot read properties of null (reading 'style')") ||
8
+ msg.includes("cannot read properties of null (reading 'queryselector')") ||
9
+ msg.includes("cannot read properties of null (reading 'removechild')"));
10
+ }
11
+ function runFallbackChallengeOpen(excluding) {
12
+ const globals = getSiaraShieldGlobals();
13
+ const candidates = ['OpenCaptchaSlid', 'GetCyberSiara', 'Open_Pluin', 'Open_Plugin', 'Open_Plugin_'];
14
+ for (const name of candidates) {
15
+ if (name === excluding)
16
+ continue;
17
+ const fn = globals[name];
18
+ if (typeof fn !== 'function')
19
+ continue;
20
+ try {
21
+ fn();
22
+ return;
23
+ }
24
+ catch {
25
+ // Try next candidate.
26
+ }
27
+ }
28
+ }
29
+ function wrapVendorOpenFunction(name) {
30
+ const globals = getSiaraShieldGlobals();
31
+ const marker = `${WRAPPED_FN_PREFIX}${name}`;
32
+ if (globals[marker] === true)
33
+ return;
34
+ const candidate = globals[name];
35
+ if (typeof candidate !== 'function')
36
+ return;
37
+ const original = candidate;
38
+ globals[name] = ((...args) => {
39
+ try {
40
+ return original(...args);
41
+ }
42
+ catch (error) {
43
+ if (!isKnownVendorNullDomError(error)) {
44
+ throw error;
45
+ }
46
+ // Vendor challenge opener hit a missing DOM node.
47
+ // Try alternative open functions so challenge can still render.
48
+ runFallbackChallengeOpen(name);
49
+ return undefined;
50
+ }
51
+ });
52
+ globals[marker] = true;
53
+ }
54
+ function installVerifiedSubmitTokenBridge() {
55
+ const globals = getSiaraShieldGlobals();
56
+ if (globals[VENDOR_TOKEN_BRIDGE_KEY])
57
+ return;
58
+ const patchAjaxOwner = (owner) => {
59
+ if (!owner || typeof owner.ajax !== 'function')
60
+ return;
61
+ const originalAjax = owner.ajax.bind(owner);
62
+ owner.ajax = ((...args) => {
63
+ const firstArg = args[0];
64
+ if (!firstArg || typeof firstArg !== 'object') {
65
+ return originalAjax(...args);
66
+ }
67
+ const options = firstArg;
68
+ const url = String(options['url'] ?? '').toLowerCase();
69
+ const originalSuccess = options['success'];
70
+ if (!url.includes('/submitcaptcha/verifiedsubmit') || typeof originalSuccess !== 'function') {
71
+ return originalAjax(options);
72
+ }
73
+ options['success'] = ((response, ...rest) => {
74
+ const payload = response;
75
+ const maybeTokenRaw = payload?.data ?? payload?.Data;
76
+ if (typeof maybeTokenRaw === 'string' && maybeTokenRaw.trim()) {
77
+ globals.CyberSiaraToken = maybeTokenRaw.trim();
78
+ }
79
+ return originalSuccess(response, ...rest);
80
+ });
81
+ return originalAjax(options);
82
+ });
83
+ };
84
+ patchAjaxOwner(globals.$);
85
+ patchAjaxOwner(globals.JQuryName);
86
+ globals[VENDOR_TOKEN_BRIDGE_KEY] = true;
87
+ }
88
+ export function installVendorChallengeRuntimePatch() {
89
+ const globals = getSiaraShieldGlobals();
90
+ if (globals[VENDOR_RUNTIME_PATCH_KEY])
91
+ return;
92
+ wrapVendorOpenFunction('Open_Pluin');
93
+ wrapVendorOpenFunction('Open_Plugin');
94
+ wrapVendorOpenFunction('Open_Plugin_');
95
+ installVerifiedSubmitTokenBridge();
96
+ globals[VENDOR_RUNTIME_PATCH_KEY] = true;
97
+ }
98
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lhcmEtc2hpZWxkLXZlbmRvci1ydW50aW1lLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvc2lhcmFzaGllbGQtd29ya3NwYWNlL3NyYy9saWIvc2lhcmEtc2hpZWxkLXZlbmRvci1ydW50aW1lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRS9ELE1BQU0sd0JBQXdCLEdBQUcsNENBQTRDLENBQUM7QUFDOUUsTUFBTSx1QkFBdUIsR0FBRywyQ0FBMkMsQ0FBQztBQUM1RSxNQUFNLGlCQUFpQixHQUFHLGdDQUFnQyxDQUFDO0FBTTNELFNBQVMseUJBQXlCLENBQUMsS0FBYztJQUMvQyxNQUFNLEdBQUcsR0FBRyxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ3JHLE9BQU8sQ0FDTCxHQUFHLENBQUMsUUFBUSxDQUFDLGtEQUFrRCxDQUFDO1FBQ2hFLEdBQUcsQ0FBQyxRQUFRLENBQUMsMERBQTBELENBQUM7UUFDeEUsR0FBRyxDQUFDLFFBQVEsQ0FBQyx3REFBd0QsQ0FBQyxDQUN2RSxDQUFDO0FBQ0osQ0FBQztBQUVELFNBQVMsd0JBQXdCLENBQUMsU0FBK0I7SUFDL0QsTUFBTSxPQUFPLEdBQUcscUJBQXFCLEVBQWlELENBQUM7SUFDdkYsTUFBTSxVQUFVLEdBQTJCLENBQUMsaUJBQWlCLEVBQUUsZUFBZSxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsY0FBYyxDQUFDLENBQUM7SUFFN0gsS0FBSyxNQUFNLElBQUksSUFBSSxVQUFVLEVBQUUsQ0FBQztRQUM5QixJQUFJLElBQUksS0FBSyxTQUFTO1lBQUUsU0FBUztRQUNqQyxNQUFNLEVBQUUs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RSxJQUFJLENBQUM7Z0JBQ3JELElBQUksT0FBTyxhQUFhLEtBQUssUUFBUSxJQUFJLGFBQWEsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDO29CQUM5RCxPQUFPLENBQUMsZUFBZSxHQUFHLGFBQWEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDakQsQ0FBQztnQkFFRCxPQUFRLGVBQXFELENBQUMsUUFBUSxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7WUFDbkYsQ0FBQyxDQUFZLENBQUM7WUFFZCxPQUFPLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMvQixDQUFDLENBQXNCLENBQUM7SUFDMUIsQ0FBQyxDQUFDO0lBRUYsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMxQixjQUFjLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ2xDLE9BQU8sQ0FBQyx1QkFBdUIsQ0FBQyxHQUFHLElBQUksQ0FBQztBQUMxQyxDQUFDO0FBRUQsTUFBTSxVQUFVLGtDQUFrQztJQUNoRCxNQUFNLE9BQU8sR0FBRyxxQkFBcUIsRUFFcEMsQ0FBQztJQUNGLElBQUksT0FBTyxDQUFDLHdCQUF3QixDQUFDO1FBQUUsT0FBTztJQUU5QyxzQkFBc0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUNyQyxzQkFBc0IsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUN0QyxzQkFBc0IsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUN2QyxnQ0FBZ0MsRUFBRSxDQUFDO0lBQ25DLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQyxHQUFHLElBQUksQ0FBQztBQUMzQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZ2V0U2lhcmFTaGllbGRHbG9iYWxzIH0gZnJvbSAnLi9zaWFyYS1zaGllbGQuZ2xvYmFscyc7XHJcblxyXG5jb25zdCBWRU5ET1JfUlVOVElNRV9QQVRDSF9LRVkgPSAnX19zaWFyYVNoaWVsZFZlbmRvclJ1bnRpbWVQYXRjaEluc3RhbGxlZF9fJztcclxuY29uc3QgVkVORE9SX1RPS0VOX0JSSURHRV9LRVkgPSAnX19zaWFyYVNoaWVsZFZlbmRvclRva2VuQnJpZGdlSW5zdGFsbGVkX18nO1xyXG5jb25zdCBXUkFQUEVEX0ZOX1BSRUZJWCA9ICdfX3NpYXJhU2hpZWxkV3JhcHBlZFZlbmRvckZuX18nO1xyXG5cclxudHlwZSBWZW5kb3JGbk5hbWUgPSAnT3Blbl9QbHVpbicgfCAnT3Blbl9QbHVnaW4nIHwgJ09wZW5fUGx1Z2luXyc7XHJcbnR5cGUgT3B0aW9uYWxWZW5kb3JGbk5hbWUgPSBWZW5kb3JGbk5hbWUgfCAnT3BlbkNhcHRjaGFTbGlkJyB8ICdHZXRDeWJlclNpYXJhJztcclxudHlwZSBWZW5kb3JGbiA9ICguLi5hcmdzOiB1bmtub3duW10pID0+IHVua25vd247XHJcblxyXG5mdW5jdGlvbiBpc0tub3duVmVuZG9yTnVsbERvbUVycm9yKGVycm9yOiB1bmtub3duKTogYm9vbGVhbiB7XHJcbiAgY29uc3QgbXNnID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UudG9Mb3dlckNhc2UoKSA6IFN0cmluZyhlcnJvciA/PyAnJykudG9Mb3dlckNhc2UoKTtcclxuICByZXR1cm4gKFxyXG4gICAgbXNnLmluY2x1ZGVzKFwiY2Fubm90IHJlYWQgcHJvcGVydGllcyBvZiBudWxsIChyZWFkaW5nICdzdHlsZScpXCIpIHx8XHJcbiAgICBtc2cuaW5jbHVkZXMoXCJjYW5ub3QgcmVhZCBwcm9wZXJ0aWVzIG9mIG51bGwgKHJlYWRpbmcgJ3F1ZXJ5c2VsZWN0b3InKVwiKSB8fFxyXG4gICAgbXNnLmluY2x1ZGVzKFwiY2Fubm90IHJlYWQgcHJvcGVydGllcyBvZiBudWxsIChyZWFkaW5nICdyZW1vdmVjaGlsZCcpXCIpXHJcbiAgKTtcclxufVxyXG5cclxuZnVuY3Rpb24gcnVuRmFsbGJhY2tDaGFsbGVuZ2VPcGVuKGV4Y2x1ZGluZzogT3B0aW9uYWxWZW5kb3JGbk5hbWUpOiB2b2lkIHtcclxuICBjb25zdCBnbG9iYWxzID0gZ2V0U2lhcmFTaGllbGRHbG9iYWxzKCkgYXMgdHlwZW9mIGdsb2JhbFRoaXMgJiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcclxuICBjb25zdCBjYW5kaWRhdGVzOiBPcHRpb25hbFZlbmRvckZuTmFtZVtdID0gWydPcGVuQ2FwdGNoYVNsaWQnLCAnR2V0Q3liZXJTaWFyYScsICdPcGVuX1BsdWluJywgJ09wZW5fUGx1Z2luJywgJ09wZW5fUGx1Z2luXyddO1xyXG5cclxuICBmb3IgKGNvbnN0IG5hbWUgb2YgY2FuZGlkYXRlcykge1xyXG4gICAgaWYgKG5hbWUgPT09IGV4Y2x1ZGluZykgY29udGludWU7XHJcbiAgICBjb25zdCBmbiA9IGdsb2JhbHNbbmFtZV07XHJcbiAgICBpZiAodHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nKSBjb250aW51ZTtcclxuICAgIHRyeSB7XHJcbiAgICAgIChmbiBhcyBWZW5kb3JGbikoKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfSBjYXRjaCB7XHJcbiAgICAgIC8vIFRyeSBuZXh0IGNhbmRpZGF0ZS5cclxuICAgIH1cclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHdyYXBWZW5kb3JPcGVuRnVuY3Rpb24obmFtZTogVmVuZG9yRm5OYW1lKTogdm9pZCB7XHJcbiAgY29uc3QgZ2xvYmFscyA9IGdldFNpYXJhU2hpZWxkR2xvYmFscygpIGFzIHR5cGVvZiBnbG9iYWxUaGlzICYgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XHJcbiAgY29uc3QgbWFya2VyID0gYCR7V1JBUFBFRF9GTl9QUkVGSVh9JHtuYW1lfWA7XHJcbiAgaWYgKGdsb2JhbHNbbWFya2VyXSA9PT0gdHJ1ZSkgcmV0dXJuO1xyXG5cclxuICBjb25zdCBjYW5kaWRhdGUgPSBnbG9iYWxzW25hbWVdO1xyXG4gIGlmICh0eXBlb2YgY2FuZGlkYXRlICE9PSAnZnVuY3Rpb24nKSByZXR1cm47XHJcblxyXG4gIGNvbnN0IG9yaWdpbmFsID0gY2FuZGlkYXRlIGFzIFZlbmRvckZuO1xyXG4gIGdsb2JhbHNbbmFtZV0gPSAoKC4uLmFyZ3M6IHVua25vd25bXSkgPT4ge1xyXG4gICAgdHJ5IHtcclxuICAgICAgcmV0dXJuIG9yaWdpbmFsKC4uLmFyZ3MpO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgaWYgKCFpc0tub3duVmVuZG9yTnVsbERvbUVycm9yKGVycm9yKSkge1xyXG4gICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBWZW5kb3IgY2hhbGxlbmdlIG9wZW5lciBoaXQgYSBtaXNzaW5nIERPTSBub2RlLlxyXG4gICAgICAvLyBUcnkgYWx0ZXJuYXRpdmUgb3BlbiBmdW5jdGlvbnMgc28gY2hhbGxlbmdlIGNhbiBzdGlsbCByZW5kZXIuXHJcbiAgICAgIHJ1bkZhbGxiYWNrQ2hhbGxlbmdlT3BlbihuYW1lKTtcclxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuICB9KSBhcyB1bmtub3duO1xyXG4gIGdsb2JhbHNbbWFya2VyXSA9IHRydWU7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGluc3RhbGxWZXJpZmllZFN1Ym1pdFRva2VuQnJpZGdlKCk6IHZvaWQge1xyXG4gIGNvbnN0IGdsb2JhbHMgPSBnZXRTaWFyYVNoaWVsZEdsb2JhbHMoKSBhcyB0eXBlb2YgZ2xvYmFsVGhpcyAmIHtcclxuICAgIFtWRU5ET1JfVE9LRU5fQlJJREdFX0tFWV0/OiBib29sZWFuO1xyXG4gICAgSlF1cnlOYW1lPzogeyBhamF4PzogKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gdW5rbm93biB9O1xyXG4gICAgJD86IHsgYWpheD86ICguLi5hcmdzOiB1bmtub3duW10pID0+IHVua25vd24gfTtcclxuICAgIEN5YmVyU2lhcmFUb2tlbj86IHN0cmluZztcclxuICB9O1xyXG4gIGlmIChnbG9iYWxzW1ZFTkRPUl9UT0tFTl9CUklER0VfS0VZXSkgcmV0dXJuO1xyXG5cclxuICBjb25zdCBwYXRjaEFqYXhPd25lciA9IChvd25lcjogeyBhamF4PzogKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gdW5rbm93biB9IHwgdW5kZWZpbmVkKTogdm9pZCA9PiB7XHJcbiAgICBpZiAoIW93bmVyIHx8IHR5cGVvZiBvd25lci5hamF4ICE9PSAnZnVuY3Rpb24nKSByZXR1cm47XHJcbiAgICBjb25zdCBvcmlnaW5hbEFqYXggPSBvd25lci5hamF4LmJpbmQob3duZXIpO1xyXG5cclxuICAgIG93bmVyLmFqYXggPSAoKC4uLmFyZ3M6IHVua25vd25bXSkgPT4ge1xyXG4gICAgICBjb25zdCBmaXJzdEFyZyA9IGFyZ3NbMF07XHJcbiAgICAgIGlmICghZmlyc3RBcmcgfHwgdHlwZW9mIGZpcnN0QXJnICE9PSAnb2JqZWN0Jykge1xyXG4gICAgICAgIHJldHVybiBvcmlnaW5hbEFqYXgoLi4uYXJncyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSBmaXJzdEFyZyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcclxuICAgICAgY29uc3QgdXJsID0gU3RyaW5nKG9wdGlvbnNbJ3VybCddID8/ICcnKS50b0xvd2VyQ2FzZSgpO1xyXG4gICAgICBjb25zdCBvcmlnaW5hbFN1Y2Nlc3MgPSBvcHRpb25zWydzdWNjZXNzJ107XHJcbiAgICAgIGlmICghdXJsLmluY2x1ZGVzKCcvc3VibWl0Y2FwdGNoYS92ZXJpZmllZHN1Ym1pdCcpIHx8IHR5cGVvZiBvcmlnaW5hbFN1Y2Nlc3MgIT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICByZXR1cm4gb3JpZ2luYWxBamF4KG9wdGlvbnMpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBvcHRpb25zWydzdWNjZXNzJ10gPSAoKHJlc3BvbnNlOiB1bmtub3duLCAuLi5yZXN0OiB1bmtub3duW10pID0+IHtcclxuICAgICAgICBjb25zdCBwYXlsb2FkID0gcmVzcG9uc2UgYXMgeyBkYXRhPzogdW5rbm93bjsgRGF0YT86IHVua25vd24gfSB8IG51bGw7XHJcbiAgICAgICAgY29uc3QgbWF5YmVUb2tlblJhdyA9IHBheWxvYWQ/LmRhdGEgPz8gcGF5bG9hZD8uRGF0YTtcclxuICAgICAgICBpZiAodHlwZW9mIG1heWJlVG9rZW5SYXcgPT09ICdzdHJpbmcnICYmIG1heWJlVG9rZW5SYXcudHJpbSgpKSB7XHJcbiAgICAgICAgICBnbG9iYWxzLkN5YmVyU2lhcmFUb2tlbiA9IG1heWJlVG9rZW5SYXcudHJpbSgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIChvcmlnaW5hbFN1Y2Nlc3MgYXMgKC4uLmZuQXJnczogdW5rbm93bltdKSA9PiB1bmtub3duKShyZXNwb25zZSwgLi4ucmVzdCk7XHJcbiAgICAgIH0pIGFzIHVua25vd247XHJcblxyXG4gICAgICByZXR1cm4gb3JpZ2luYWxBamF4KG9wdGlvbnMpO1xyXG4gICAgfSkgYXMgdHlwZW9mIG93bmVyLmFqYXg7XHJcbiAgfTtcclxuXHJcbiAgcGF0Y2hBamF4T3duZXIoZ2xvYmFscy4kKTtcclxuICBwYXRjaEFqYXhPd25lcihnbG9iYWxzLkpRdXJ5TmFtZSk7XHJcbiAgZ2xvYmFsc1tWRU5ET1JfVE9LRU5fQlJJREdFX0tFWV0gPSB0cnVlO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gaW5zdGFsbFZlbmRvckNoYWxsZW5nZVJ1bnRpbWVQYXRjaCgpOiB2b2lkIHtcclxuICBjb25zdCBnbG9iYWxzID0gZ2V0U2lhcmFTaGllbGRHbG9iYWxzKCkgYXMgdHlwZW9mIGdsb2JhbFRoaXMgJiB7XHJcbiAgICBbVkVORE9SX1JVTlRJTUVfUEFUQ0hfS0VZXT86IGJvb2xlYW47XHJcbiAgfTtcclxuICBpZiAoZ2xvYmFsc1tWRU5ET1JfUlVOVElNRV9QQVRDSF9LRVldKSByZXR1cm47XHJcblxyXG4gIHdyYXBWZW5kb3JPcGVuRnVuY3Rpb24oJ09wZW5fUGx1aW4nKTtcclxuICB3cmFwVmVuZG9yT3BlbkZ1bmN0aW9uKCdPcGVuX1BsdWdpbicpO1xyXG4gIHdyYXBWZW5kb3JPcGVuRnVuY3Rpb24oJ09wZW5fUGx1Z2luXycpO1xyXG4gIGluc3RhbGxWZXJpZmllZFN1Ym1pdFRva2VuQnJpZGdlKCk7XHJcbiAgZ2xvYmFsc1tWRU5ET1JfUlVOVElNRV9QQVRDSF9LRVldID0gdHJ1ZTtcclxufVxyXG4iXX0=