@panguard-ai/panguard-guard 1.8.8 → 1.8.9

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.
@@ -2606,22 +2606,45 @@
2606
2606
  t.classList.remove('show');
2607
2607
  }, 2500);
2608
2608
  }
2609
- function af(path, opts) {
2609
+ function af(path, opts, _retriesLeft) {
2610
2610
  opts = opts || {};
2611
2611
  opts.credentials = 'same-origin';
2612
2612
  return fetch(path, opts).then(function (r) {
2613
2613
  if (r.status === 401) {
2614
+ // A 401 is rejected at the auth gate BEFORE the handler runs, so the
2615
+ // request had no side effect and is safe to retry. A proxying or
2616
+ // embedded browser (and some cross-origin isolation modes) can drop
2617
+ // the HttpOnly SameSite=Strict launch cookie mid-flight, so a single
2618
+ // /api call 401s even though the session is valid — the next one
2619
+ // succeeds. Overview hid this by polling; a one-shot tab load (Rules,
2620
+ // Skills, Coverage, Runtime, Settings) did NOT — it failed to empty on
2621
+ // the first flap. So retry a few times before declaring the dashboard
2622
+ // unauthenticated; a genuinely bad/absent token still 401s every retry
2623
+ // and falls through to the overlay.
2624
+ var left = _retriesLeft === undefined ? 4 : _retriesLeft;
2625
+ if (left > 0) {
2626
+ return new Promise(function (resolve) {
2627
+ setTimeout(function () {
2628
+ resolve(af(path, opts, left - 1));
2629
+ }, 250);
2630
+ });
2631
+ }
2614
2632
  var wl = document.getElementById('wl');
2615
2633
  if (wl) wl.textContent = 'Invalid token';
2616
- // An unauthenticated visit (bare URL, expired/cleared cookie, wrong
2617
- // token) used to silently no-op and leave a static green "Active"
2618
- // badge — a dead end with no path forward. Render an explicit screen
2619
- // that tells the user exactly how to get an authenticated URL.
2620
2634
  showUnauthenticated();
2635
+ return r;
2621
2636
  }
2637
+ // A real success proves the session IS authenticated — clear any overlay
2638
+ // a transient 401 flap put up, so the dashboard heals itself.
2639
+ if (r.ok && _unauthShown) hideUnauthenticated();
2622
2640
  return r;
2623
2641
  });
2624
2642
  }
2643
+ function hideUnauthenticated() {
2644
+ _unauthShown = false;
2645
+ var ov = document.getElementById('unauth-overlay');
2646
+ if (ov) ov.style.display = 'none';
2647
+ }
2625
2648
  /* Explicit unauthenticated state: the cookie that authorizes /api/* is
2626
2649
  minted only by opening the launch URL `pga up` prints. A bare visit has
2627
2650
  no cookie, so every /api/* call 401s. Instead of a fake-green dead end,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@panguard-ai/panguard-guard",
3
- "version": "1.8.8",
3
+ "version": "1.8.9",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -46,13 +46,13 @@
46
46
  "js-yaml": "^4.1.0",
47
47
  "ws": "^8.21.0",
48
48
  "zod": "^3.24.0",
49
- "@panguard-ai/core": "1.8.8",
50
- "@panguard-ai/panguard-mcp": "1.8.8",
51
- "@panguard-ai/panguard-skill-auditor": "1.8.8",
52
- "@panguard-ai/panguard-trap": "1.8.8",
53
- "@panguard-ai/security-hardening": "1.8.8",
54
- "@panguard-ai/scan-core": "1.8.8",
55
- "@panguard-ai/atr": "1.8.8"
49
+ "@panguard-ai/atr": "1.8.9",
50
+ "@panguard-ai/core": "1.8.9",
51
+ "@panguard-ai/panguard-trap": "1.8.9",
52
+ "@panguard-ai/panguard-skill-auditor": "1.8.9",
53
+ "@panguard-ai/scan-core": "1.8.9",
54
+ "@panguard-ai/panguard-mcp": "1.8.9",
55
+ "@panguard-ai/security-hardening": "1.8.9"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@types/js-yaml": "^4.0.9",