@sandprivacy/sandgate 0.1.5 → 0.1.6
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/dist/relay/pwa-page.js +43 -21
- package/package.json +1 -1
package/dist/relay/pwa-page.js
CHANGED
|
@@ -38,8 +38,14 @@ export function pwaManifest(opts) {
|
|
|
38
38
|
export const PWA_SW = `
|
|
39
39
|
self.addEventListener("install", function () { self.skipWaiting(); });
|
|
40
40
|
self.addEventListener("activate", function (e) { e.waitUntil(self.clients.claim()); });
|
|
41
|
-
// A fetch handler is required for Chrome's install prompt
|
|
42
|
-
|
|
41
|
+
// A fetch handler is required for Chrome's install prompt. Handle ONLY
|
|
42
|
+
// same-origin GETs: on iOS 16.4+, respondWith(fetch(request)) on POSTs
|
|
43
|
+
// (bodies) throws Internal error and silently kills subscribe/decision
|
|
44
|
+
// calls — anything we return from lets the browser handle natively.
|
|
45
|
+
self.addEventListener("fetch", function (e) {
|
|
46
|
+
if (e.request.method !== "GET") return;
|
|
47
|
+
e.respondWith(fetch(e.request));
|
|
48
|
+
});
|
|
43
49
|
self.addEventListener("push", function (e) {
|
|
44
50
|
e.waitUntil((async function () {
|
|
45
51
|
await self.registration.showNotification("sandgate", {
|
|
@@ -193,7 +199,8 @@ export const PWA_HTML = `<!doctype html>
|
|
|
193
199
|
.setup input {
|
|
194
200
|
width: 100%; padding: 12px 14px; margin: 14px 0 10px;
|
|
195
201
|
background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
|
|
196
|
-
|
|
202
|
+
/* 16px minimum: below that, iOS Safari auto-zooms into focused inputs. */
|
|
203
|
+
color: var(--ink); font: 16px ui-monospace, monospace;
|
|
197
204
|
}
|
|
198
205
|
.setup input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
|
|
199
206
|
|
|
@@ -442,11 +449,20 @@ export const PWA_HTML = `<!doctype html>
|
|
|
442
449
|
return true;
|
|
443
450
|
}
|
|
444
451
|
|
|
452
|
+
function showPushError(err) {
|
|
453
|
+
setStatus("push error", "err");
|
|
454
|
+
alert(
|
|
455
|
+
"Notifications could not be enabled: " +
|
|
456
|
+
(err && err.message ? err.name + " — " + err.message : err) +
|
|
457
|
+
"\\n\\nOn iPhone this requires iOS 16.4+, the app installed on the home screen, and Lockdown Mode off."
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
|
|
445
461
|
function offerPush() {
|
|
446
462
|
if (!("Notification" in window) || !("PushManager" in window)) return;
|
|
447
463
|
if (isIOS && !standalone) return; // impossible in Safari tabs; banner handles install
|
|
448
464
|
if (Notification.permission === "granted") {
|
|
449
|
-
enablePush().catch(
|
|
465
|
+
enablePush().catch(showPushError);
|
|
450
466
|
return;
|
|
451
467
|
}
|
|
452
468
|
if (Notification.permission === "denied") return;
|
|
@@ -457,7 +473,7 @@ export const PWA_HTML = `<!doctype html>
|
|
|
457
473
|
'<button class="act" id="pushBtn">Enable notifications</button>';
|
|
458
474
|
bannerEl.appendChild(b);
|
|
459
475
|
document.getElementById("pushBtn").addEventListener("click", function () {
|
|
460
|
-
enablePush().catch(
|
|
476
|
+
enablePush().catch(showPushError);
|
|
461
477
|
});
|
|
462
478
|
}
|
|
463
479
|
offerPush();
|
|
@@ -624,22 +640,28 @@ export const PWA_HTML = `<!doctype html>
|
|
|
624
640
|
var c = cards[id];
|
|
625
641
|
if (!c || c.done) return;
|
|
626
642
|
b.disabled = true;
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
cards[id]
|
|
640
|
-
|
|
643
|
+
try {
|
|
644
|
+
var payload = await sealPayload(
|
|
645
|
+
c.pair,
|
|
646
|
+
{ requestId: c.requestId, approved: cls === "ok", ts: Date.now() },
|
|
647
|
+
"dec:" + c.requestId
|
|
648
|
+
);
|
|
649
|
+
var res = await fetch("/api/decision", {
|
|
650
|
+
method: "POST",
|
|
651
|
+
headers: { "Content-Type": "application/json" },
|
|
652
|
+
body: JSON.stringify({ pairId: c.pair.pairId, requestId: c.requestId, payload: payload }),
|
|
653
|
+
});
|
|
654
|
+
if (!res.ok) throw new Error("relay answered HTTP " + res.status);
|
|
655
|
+
if (cards[id]) {
|
|
656
|
+
recordHist(histLabel(c), cls === "ok" ? "approved" : "denied");
|
|
657
|
+
cards[id].el.remove();
|
|
658
|
+
delete cards[id];
|
|
659
|
+
}
|
|
660
|
+
ensureEmpty(Object.keys(cards).length === 0);
|
|
661
|
+
} catch (err) {
|
|
662
|
+
b.disabled = false;
|
|
663
|
+
alert("Could not send your decision: " + (err && err.message ? err.message : err));
|
|
641
664
|
}
|
|
642
|
-
ensureEmpty(Object.keys(cards).length === 0);
|
|
643
665
|
};
|
|
644
666
|
return b;
|
|
645
667
|
}
|
|
@@ -681,7 +703,7 @@ export const PWA_HTML = `<!doctype html>
|
|
|
681
703
|
input.id = "addPaste";
|
|
682
704
|
input.placeholder = "Paste a pairing link (sandgate pair)";
|
|
683
705
|
input.autocomplete = "off";
|
|
684
|
-
input.style.cssText = "width:100%;padding:10px 12px;margin-top:8px;background:var(--panel);border:1px solid var(--line);border-radius:8px;color:var(--ink);font:
|
|
706
|
+
input.style.cssText = "width:100%;padding:10px 12px;margin-top:8px;background:var(--panel);border:1px solid var(--line);border-radius:8px;color:var(--ink);font:16px ui-monospace,monospace;box-sizing:border-box;";
|
|
685
707
|
input.addEventListener("input", function (e) {
|
|
686
708
|
var parsed = parsePairing(e.target.value);
|
|
687
709
|
if (parsed && addPairing(parsed)) location.reload();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sandprivacy/sandgate",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "The human gateway for AI agents — approvals, 2FA codes and email verification, self-hosted. Your agent asks; you decide; secrets never touch the LLM.",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"type": "module",
|