local-operator-ui 0.33.15 → 0.33.17
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/out/main/index.js +490 -90
- package/out/preload/index.js +2087 -6
- package/out/renderer/assets/{_basePickBy-Bw96TDKM.js → _basePickBy-C6nvmA2O.js} +1 -1
- package/out/renderer/assets/{_baseUniq-BwH2fs71.js → _baseUniq-D-t5jxGe.js} +1 -1
- package/out/renderer/assets/{agent-details-page-CVnB4TCA.js → agent-details-page-mE7vTnG6.js} +2 -2
- package/out/renderer/assets/{agent-hub-page-CDw5-Cwg.js → agent-hub-page-CaqTDoWq.js} +2 -2
- package/out/renderer/assets/{agents-page-Bb8kUb9C.js → agents-page-DA1i3841.js} +3 -3
- package/out/renderer/assets/{arc-e8rYtxak.js → arc-DImPBqfb.js} +1 -1
- package/out/renderer/assets/{architectureDiagram-IEHRJDOE-UzztVbBZ.js → architectureDiagram-IEHRJDOE-f1d6V-bd.js} +1 -1
- package/out/renderer/assets/{blockDiagram-JOT3LUYC-Fj4mKpDj.js → blockDiagram-JOT3LUYC-CMcoLCyx.js} +1 -1
- package/out/renderer/assets/{book-open-Bpq_4qho.js → book-open-BHF9CFNT.js} +1 -1
- package/out/renderer/assets/browser-page-s-y7nb7P.js +1 -0
- package/out/renderer/assets/{browser-webauthn-prompt-_H81qUMy.js → browser-webauthn-prompt-DTozoEE6.js} +1 -1
- package/out/renderer/assets/{c4Diagram-VJAJSXHY-B7sLtwgq.js → c4Diagram-VJAJSXHY-Ddsy3KqL.js} +1 -1
- package/out/renderer/assets/channel-JtmJZ6rG.js +1 -0
- package/out/renderer/assets/{chunk-4BMEZGHF-Bfh9czP4.js → chunk-4BMEZGHF-CDjCGQ2m.js} +1 -1
- package/out/renderer/assets/{chunk-A2AXSNBT-CGstChAp.js → chunk-A2AXSNBT-Baqc6iAL.js} +1 -1
- package/out/renderer/assets/{chunk-AEK57VVT-BilH6T0d.js → chunk-AEK57VVT-CCyw5JVf.js} +1 -1
- package/out/renderer/assets/{chunk-D6G4REZN-5bv4yssM.js → chunk-D6G4REZN-EvFtaW-d.js} +1 -1
- package/out/renderer/assets/{chunk-RZ5BOZE2-DC3kTCaU.js → chunk-RZ5BOZE2-GTO1bXU_.js} +1 -1
- package/out/renderer/assets/{chunk-XZIHB7SX-BFTAzsGR.js → chunk-XZIHB7SX-DoyGDc-_.js} +1 -1
- package/out/renderer/assets/classDiagram-GIVACNV2-BI50x_TJ.js +1 -0
- package/out/renderer/assets/classDiagram-v2-COTLJTTW-BI50x_TJ.js +1 -0
- package/out/renderer/assets/clone-XzOZppxb.js +1 -0
- package/out/renderer/assets/{console-mirror-CRDd2xJz.js → console-mirror-a7yB-s_0.js} +1 -1
- package/out/renderer/assets/{consoleCapture-CFEB_xm8.js → consoleCapture-CesHMPtd.js} +1 -1
- package/out/renderer/assets/{conversation-input-sync-DzSA_zJM.js → conversation-input-sync-B4PMPza6.js} +235 -236
- package/out/renderer/assets/{dagre-OKDRZEBW-D9yuN6oR.js → dagre-OKDRZEBW-JuntHNlb.js} +1 -1
- package/out/renderer/assets/{diagram-SSKATNLV-F788WwdC.js → diagram-SSKATNLV-DyRsGLiH.js} +1 -1
- package/out/renderer/assets/{diagram-VNBRO52H-BN1k5oTd.js → diagram-VNBRO52H-B9gGTGdS.js} +1 -1
- package/out/renderer/assets/{erDiagram-Q7BY3M3F-DSe9sJa2.js → erDiagram-Q7BY3M3F-B26A6UsD.js} +1 -1
- package/out/renderer/assets/{error-boundary-k-Quyoe4.js → error-boundary-D9cFOE8L.js} +1 -1
- package/out/renderer/assets/{flowDiagram-4HSFHLVR-D4V_VTWT.js → flowDiagram-4HSFHLVR-CitlL0-h.js} +1 -1
- package/out/renderer/assets/{ganttDiagram-APWFNJXF-1qYA1Q_a.js → ganttDiagram-APWFNJXF-BHkObFqC.js} +1 -1
- package/out/renderer/assets/{gitGraphDiagram-7IBYFJ6S-tgv2fONv.js → gitGraphDiagram-7IBYFJ6S-PmAB3iwh.js} +1 -1
- package/out/renderer/assets/{graph-OUFkyGJ7.js → graph-kQDtoPNV.js} +1 -1
- package/out/renderer/assets/{index-CiuOYo7h.js → index-31_gb9wt.js} +153 -153
- package/out/renderer/assets/index-BDUcsMbE.css +1 -0
- package/out/renderer/assets/{index-aaKerQmB.js → index-CoTpZA1x.js} +1 -1
- package/out/renderer/assets/{index-DS4ISYED.js → index-DatO4ILn.js} +1 -1
- package/out/renderer/assets/{index-BUuTlpWL.js → index-WYMv0ga-.js} +4 -4
- package/out/renderer/assets/{infoDiagram-PH2N3AL5-CytAifil.js → infoDiagram-PH2N3AL5-Bthl21hU.js} +1 -1
- package/out/renderer/assets/{installer-CyXYBRth.js → installer-0DM8a2O5.js} +1 -1
- package/out/renderer/assets/{journeyDiagram-U35MCT3I-Du6tcblG.js → journeyDiagram-U35MCT3I-CS2dhA53.js} +1 -1
- package/out/renderer/assets/{kanban-definition-NDS4AKOZ-D_Q9JXE0.js → kanban-definition-NDS4AKOZ-BuYZJpFN.js} +1 -1
- package/out/renderer/assets/{layout-DI3MU0DE.js → layout-BDAgAb56.js} +1 -1
- package/out/renderer/assets/{legacy-agents-page-DY0tfoNn.js → legacy-agents-page-ByVaCmw5.js} +4 -4
- package/out/renderer/assets/{mermaid.core-Cdm_DjcZ.js → mermaid.core-BNyEpqlY.js} +5 -5
- package/out/renderer/assets/{mesh-page-CaZr32iH.js → mesh-page-Bpcc_Lcj.js} +1 -1
- package/out/renderer/assets/{mindmap-definition-ALO5MXBD-C6tJSFYz.js → mindmap-definition-ALO5MXBD-Km_IXn-L.js} +1 -1
- package/out/renderer/assets/mini-CueIa1FR.js +1 -0
- package/out/renderer/assets/{org-surface-gate-XpwDti00.js → org-surface-gate-BNNGp-Zg.js} +1 -1
- package/out/renderer/assets/{page-header-9-FZXnc7.js → page-header-Bj15XDRT.js} +1 -1
- package/out/renderer/assets/{pieDiagram-IB7DONF6-rd7xWVzu.js → pieDiagram-IB7DONF6-CgQ2nspc.js} +1 -1
- package/out/renderer/assets/{projects-page-CdPnuz2S.js → projects-page-BiqCz3gt.js} +1 -1
- package/out/renderer/assets/{quadrantDiagram-7GDLP6J5-Ah6kO_WF.js → quadrantDiagram-7GDLP6J5-C9VRMhAK.js} +1 -1
- package/out/renderer/assets/{radar-MK3ICKWK-Cdm1PbQe.js → radar-MK3ICKWK-Ca5oUXiG.js} +1 -1
- package/out/renderer/assets/{radient-auth-buttons-CwWDtLSt.js → radient-auth-buttons-wx9BULzn.js} +1 -1
- package/out/renderer/assets/{requirementDiagram-KVF5MWMF-DkfvehXa.js → requirementDiagram-KVF5MWMF-Dl3vif4l.js} +1 -1
- package/out/renderer/assets/{sankeyDiagram-QLVOVGJD-BwVspMro.js → sankeyDiagram-QLVOVGJD-Dp6MvwZ8.js} +1 -1
- package/out/renderer/assets/{schedules-page-D2pTKTNQ.js → schedules-page-BlByjsrj.js} +1 -1
- package/out/renderer/assets/{sequenceDiagram-X6HHIX6F-Cxmrx9WA.js → sequenceDiagram-X6HHIX6F-DBC8EXEO.js} +1 -1
- package/out/renderer/assets/{settings-page-BjczVQin.js → settings-page-BPjWIUIw.js} +7 -7
- package/out/renderer/assets/{settings-section-BFcSTphB.js → settings-section-C9vsPtq9.js} +1 -1
- package/out/renderer/assets/{stateDiagram-DGXRK772-BaDfgxSN.js → stateDiagram-DGXRK772-ZaVJUkT9.js} +1 -1
- package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-rmZg0oCb.js +1 -0
- package/out/renderer/assets/{timeline-definition-BDJGKUSR-Dth6RDXc.js → timeline-definition-BDJGKUSR-D-lVRJfh.js} +1 -1
- package/out/renderer/assets/{ui-preferences-store-yedh94_3.js → ui-preferences-store-CGuje1Kj.js} +1 -1
- package/out/renderer/assets/{use-download-agent-mutation-D3P9ekSI.js → use-download-agent-mutation-DwLETtX-.js} +2 -2
- package/out/renderer/assets/{use-memberships-query-c9zgxm-U.js → use-memberships-query-BO0DbD7e.js} +1 -1
- package/out/renderer/assets/{use-session-snapshot-CC2ORxgW.js → use-session-snapshot-CrrB5aTS.js} +1 -1
- package/out/renderer/assets/{xychartDiagram-VJFVF3MP-DKngG8u6.js → xychartDiagram-VJFVF3MP-Dfu_vxvq.js} +1 -1
- package/out/renderer/console-capture.html +5 -5
- package/out/renderer/index.html +7 -7
- package/out/renderer/installer.html +4 -4
- package/out/renderer/mini.html +7 -7
- package/package.json +4 -2
- package/out/renderer/assets/browser-page-IjluNvg-.js +0 -1
- package/out/renderer/assets/channel-BXLS0K-G.js +0 -1
- package/out/renderer/assets/classDiagram-GIVACNV2-DEfXxH6c.js +0 -1
- package/out/renderer/assets/classDiagram-v2-COTLJTTW-DEfXxH6c.js +0 -1
- package/out/renderer/assets/clone-DzW9XtSk.js +0 -1
- package/out/renderer/assets/index-BpcpaIkr.css +0 -1
- package/out/renderer/assets/mini-1AoP5pMh.js +0 -1
- package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-zyCgmErW.js +0 -1
package/out/main/index.js
CHANGED
|
@@ -1242,7 +1242,19 @@ const desktopRequestUnion = zod.z.discriminatedUnion("op", [
|
|
|
1242
1242
|
command: id$1,
|
|
1243
1243
|
name: zod.z.string().max(128).optional()
|
|
1244
1244
|
}).strict(),
|
|
1245
|
-
zod.z.object({
|
|
1245
|
+
zod.z.object({
|
|
1246
|
+
op: zod.z.literal("models.catalogue"),
|
|
1247
|
+
live: zod.z.boolean().optional(),
|
|
1248
|
+
/*
|
|
1249
|
+
* Which view of the catalogue to answer with: `usable` (the rows this
|
|
1250
|
+
* machine can run, plus the session's current model) or `all`. Absent
|
|
1251
|
+
* means `all`, which is also what a backend that predates the
|
|
1252
|
+
* parameter does with it — the picker stays correct either way, because
|
|
1253
|
+
* a compile-time-correct request against an old backend is filtered
|
|
1254
|
+
* client-side by `scopeCatalogue`.
|
|
1255
|
+
*/
|
|
1256
|
+
scope: zod.z.enum(["usable", "all"]).optional()
|
|
1257
|
+
}).strict(),
|
|
1246
1258
|
zod.z.object({
|
|
1247
1259
|
op: zod.z.literal("usage.get"),
|
|
1248
1260
|
provider: id$1.optional(),
|
|
@@ -3106,11 +3118,13 @@ function desktopEndpoint(request) {
|
|
|
3106
3118
|
path: `/v1/desktop/sessions/${request.sessionId}/command-entities?command=${encodeURIComponent(request.command)}${request.name ? `&name=${encodeURIComponent(request.name)}` : ""}`,
|
|
3107
3119
|
method: "GET"
|
|
3108
3120
|
};
|
|
3109
|
-
case "models.catalogue":
|
|
3121
|
+
case "models.catalogue": {
|
|
3122
|
+
const scope = request.scope ? `&scope=${request.scope}` : "";
|
|
3110
3123
|
return {
|
|
3111
|
-
path: `/v1/desktop/models?live=${request.live ?? false}`,
|
|
3124
|
+
path: `/v1/desktop/models?live=${request.live ?? false}${scope}`,
|
|
3112
3125
|
method: "GET"
|
|
3113
3126
|
};
|
|
3127
|
+
}
|
|
3114
3128
|
case "usage.get": {
|
|
3115
3129
|
const query = new URLSearchParams({
|
|
3116
3130
|
live: String(request.live ?? false),
|
|
@@ -3484,6 +3498,7 @@ function desktopEndpoint(request) {
|
|
|
3484
3498
|
const MAX_PROBE_PATHS = 64;
|
|
3485
3499
|
const DIRECTORY_ENTRY_LIMIT = 200;
|
|
3486
3500
|
const MAX_FILE_READ_BYTES = 64 * 1024 * 1024;
|
|
3501
|
+
const EXTERNAL_OPEN_REFUSED_CHANNEL = "external-open-refused";
|
|
3487
3502
|
const MINI_VIEW_SUMMONED = "mini-view:summoned";
|
|
3488
3503
|
const MINI_VIEW_DISMISS = "mini-view:dismiss";
|
|
3489
3504
|
const MINI_VIEW_REGISTRATION = "mini-view:registration";
|
|
@@ -3827,9 +3842,9 @@ function classifyRecord(record, now, liveness = recordPidLiveness(record, now))
|
|
|
3827
3842
|
return age > HEARTBEAT_TIMEOUT_MS ? "wedged" : "live";
|
|
3828
3843
|
}
|
|
3829
3844
|
function recordAddress(record) {
|
|
3830
|
-
return addressOf("http:", canonicalHost(record.host), record.port);
|
|
3845
|
+
return addressOf("http:", canonicalHost$1(record.host), record.port);
|
|
3831
3846
|
}
|
|
3832
|
-
function canonicalHost(host) {
|
|
3847
|
+
function canonicalHost$1(host) {
|
|
3833
3848
|
const bare = host.startsWith("[") && host.endsWith("]") ? host.slice(1, -1) : host;
|
|
3834
3849
|
const unqualified = bare.endsWith(".") ? bare.slice(0, -1) : bare;
|
|
3835
3850
|
const lower = unqualified.toLowerCase();
|
|
@@ -4098,7 +4113,7 @@ function normaliseAddress(url) {
|
|
|
4098
4113
|
const port = parsed.port || (parsed.protocol === "https:" ? "443" : "80");
|
|
4099
4114
|
return addressOf(
|
|
4100
4115
|
parsed.protocol,
|
|
4101
|
-
canonicalHost(parsed.hostname),
|
|
4116
|
+
canonicalHost$1(parsed.hostname),
|
|
4102
4117
|
Number(port)
|
|
4103
4118
|
);
|
|
4104
4119
|
} catch {
|
|
@@ -42824,6 +42839,374 @@ function attachWindowChrome(options) {
|
|
|
42824
42839
|
};
|
|
42825
42840
|
return { sync, dispose };
|
|
42826
42841
|
}
|
|
42842
|
+
const ALLOW = { allowed: true };
|
|
42843
|
+
const deny = (reason) => ({ allowed: false, reason });
|
|
42844
|
+
const EXTERNAL_SCHEMES = /* @__PURE__ */ new Set([
|
|
42845
|
+
"https:",
|
|
42846
|
+
"http:",
|
|
42847
|
+
"mailto:"
|
|
42848
|
+
]);
|
|
42849
|
+
const MAX_EXTERNAL_URL_LENGTH = 16384;
|
|
42850
|
+
const IPV4_PART = /^\d{1,3}$/;
|
|
42851
|
+
const IPV6_MAPPED_PREFIX = /^::ffff:(.+)$/;
|
|
42852
|
+
const TRAILING_DOT = /\.$/;
|
|
42853
|
+
function isPrivateIpv4(host) {
|
|
42854
|
+
const parts = host.split(".");
|
|
42855
|
+
if (parts.length !== 4) return false;
|
|
42856
|
+
const octets = [];
|
|
42857
|
+
for (const part of parts) {
|
|
42858
|
+
if (!IPV4_PART.test(part)) return false;
|
|
42859
|
+
const value = Number(part);
|
|
42860
|
+
if (value > 255) return false;
|
|
42861
|
+
octets.push(value);
|
|
42862
|
+
}
|
|
42863
|
+
const [a, b] = octets;
|
|
42864
|
+
if (a === 0 || a === 127) return true;
|
|
42865
|
+
if (a === 10) return true;
|
|
42866
|
+
if (a === 172 && b >= 16 && b <= 31) return true;
|
|
42867
|
+
if (a === 192 && b === 168) return true;
|
|
42868
|
+
if (a === 169 && b === 254) return true;
|
|
42869
|
+
return false;
|
|
42870
|
+
}
|
|
42871
|
+
function isPrivateIpv6(host) {
|
|
42872
|
+
if (host === "::" || host === "::1") return true;
|
|
42873
|
+
const mapped = IPV6_MAPPED_PREFIX.exec(host);
|
|
42874
|
+
if (mapped) {
|
|
42875
|
+
const rest = mapped[1];
|
|
42876
|
+
if (rest.includes(".")) return isPrivateIpv4(rest);
|
|
42877
|
+
const groups = rest.split(":");
|
|
42878
|
+
if (groups.length === 2) {
|
|
42879
|
+
const hi = Number.parseInt(groups[0], 16);
|
|
42880
|
+
const lo = Number.parseInt(groups[1], 16);
|
|
42881
|
+
if (Number.isFinite(hi) && Number.isFinite(lo)) {
|
|
42882
|
+
return isPrivateIpv4(
|
|
42883
|
+
[hi >> 8, hi & 255, lo >> 8, lo & 255].join(".")
|
|
42884
|
+
);
|
|
42885
|
+
}
|
|
42886
|
+
}
|
|
42887
|
+
return true;
|
|
42888
|
+
}
|
|
42889
|
+
const first = Number.parseInt(host.split(":")[0] || "0", 16);
|
|
42890
|
+
if (!Number.isFinite(first)) return true;
|
|
42891
|
+
if ((first & 65472) === 65152) return true;
|
|
42892
|
+
if ((first & 65024) === 64512) return true;
|
|
42893
|
+
return false;
|
|
42894
|
+
}
|
|
42895
|
+
const canonicalHost = (hostname) => hostname.toLowerCase().replace(TRAILING_DOT, "");
|
|
42896
|
+
function isLocalOrPrivateHost(hostname) {
|
|
42897
|
+
const host = canonicalHost(hostname);
|
|
42898
|
+
if (host === "localhost" || host.endsWith(".localhost")) return true;
|
|
42899
|
+
if (host.startsWith("[") && host.endsWith("]"))
|
|
42900
|
+
return isPrivateIpv6(host.slice(1, -1));
|
|
42901
|
+
return isPrivateIpv4(host);
|
|
42902
|
+
}
|
|
42903
|
+
function externalUrlVerdict(raw) {
|
|
42904
|
+
if (typeof raw !== "string" || raw.length === 0)
|
|
42905
|
+
return { allowed: false, reason: "not a string" };
|
|
42906
|
+
if (raw.length > MAX_EXTERNAL_URL_LENGTH)
|
|
42907
|
+
return { allowed: false, reason: "too long" };
|
|
42908
|
+
let url;
|
|
42909
|
+
try {
|
|
42910
|
+
url = new URL(raw);
|
|
42911
|
+
} catch {
|
|
42912
|
+
return { allowed: false, reason: "not a URL" };
|
|
42913
|
+
}
|
|
42914
|
+
if (!EXTERNAL_SCHEMES.has(url.protocol))
|
|
42915
|
+
return {
|
|
42916
|
+
allowed: false,
|
|
42917
|
+
reason: `scheme ${url.protocol} is not handed out`
|
|
42918
|
+
};
|
|
42919
|
+
if (url.protocol !== "mailto:") {
|
|
42920
|
+
if (url.username || url.password)
|
|
42921
|
+
return { allowed: false, reason: "URL carries credentials" };
|
|
42922
|
+
if (!url.hostname) return { allowed: false, reason: "URL has no host" };
|
|
42923
|
+
if (isLocalOrPrivateHost(url.hostname))
|
|
42924
|
+
return {
|
|
42925
|
+
allowed: false,
|
|
42926
|
+
reason: "URL names a loopback or private-network host"
|
|
42927
|
+
};
|
|
42928
|
+
} else if (/(^|[?&])attach(ment)?=/i.test(url.search)) {
|
|
42929
|
+
return { allowed: false, reason: "mailto: names an attachment" };
|
|
42930
|
+
}
|
|
42931
|
+
return { allowed: true, url: url.href };
|
|
42932
|
+
}
|
|
42933
|
+
async function openVettedExternal(raw, open2, log2) {
|
|
42934
|
+
const verdict = externalUrlVerdict(raw);
|
|
42935
|
+
if (!verdict.allowed) {
|
|
42936
|
+
log2(`[window-guard] refused to open externally: ${verdict.reason}`);
|
|
42937
|
+
return { ok: false, reason: verdict.reason };
|
|
42938
|
+
}
|
|
42939
|
+
try {
|
|
42940
|
+
await open2(verdict.url);
|
|
42941
|
+
return { ok: true };
|
|
42942
|
+
} catch (error) {
|
|
42943
|
+
const reason = `the OS could not open the URL: ${error instanceof Error ? error.message : String(error)}`;
|
|
42944
|
+
log2(`[window-guard] ${reason}`);
|
|
42945
|
+
return { ok: false, reason };
|
|
42946
|
+
}
|
|
42947
|
+
}
|
|
42948
|
+
const AUTH_HOSTS = [
|
|
42949
|
+
"accounts.google.com",
|
|
42950
|
+
"oauth.googleusercontent.com",
|
|
42951
|
+
"content.googleapis.com",
|
|
42952
|
+
"ssl.gstatic.com",
|
|
42953
|
+
"login.microsoftonline.com",
|
|
42954
|
+
"microsoftonline.com",
|
|
42955
|
+
"login.live.com",
|
|
42956
|
+
"login.windows.net",
|
|
42957
|
+
"login.microsoft.com"
|
|
42958
|
+
];
|
|
42959
|
+
const AUTH_SCHEMES = /* @__PURE__ */ new Set([
|
|
42960
|
+
"storagerelay:",
|
|
42961
|
+
"msauth:",
|
|
42962
|
+
"msftauth:"
|
|
42963
|
+
]);
|
|
42964
|
+
function isAuthPopupUrl(url) {
|
|
42965
|
+
if (url.protocol !== "https:") return false;
|
|
42966
|
+
if (url.username || url.password) return false;
|
|
42967
|
+
if (url.port !== "") return false;
|
|
42968
|
+
const host = url.hostname.toLowerCase();
|
|
42969
|
+
return AUTH_HOSTS.some(
|
|
42970
|
+
(domain) => host === domain || host.endsWith(`.${domain}`)
|
|
42971
|
+
);
|
|
42972
|
+
}
|
|
42973
|
+
function popupVerdict(raw) {
|
|
42974
|
+
if (raw === "about:blank")
|
|
42975
|
+
return {
|
|
42976
|
+
action: "deny",
|
|
42977
|
+
reason: "about:blank is refused as a popup start"
|
|
42978
|
+
};
|
|
42979
|
+
let url = null;
|
|
42980
|
+
try {
|
|
42981
|
+
url = new URL(raw);
|
|
42982
|
+
} catch {
|
|
42983
|
+
}
|
|
42984
|
+
if (url && (isAuthPopupUrl(url) || AUTH_SCHEMES.has(url.protocol)))
|
|
42985
|
+
return { action: "auth" };
|
|
42986
|
+
const external = externalUrlVerdict(raw);
|
|
42987
|
+
return external.allowed ? { action: "external", url: external.url } : { action: "deny", reason: external.reason };
|
|
42988
|
+
}
|
|
42989
|
+
function popupNavigationVerdict(rawUrl) {
|
|
42990
|
+
if (rawUrl === "about:blank") return ALLOW;
|
|
42991
|
+
let url;
|
|
42992
|
+
try {
|
|
42993
|
+
url = new URL(rawUrl);
|
|
42994
|
+
} catch {
|
|
42995
|
+
return deny("not a URL");
|
|
42996
|
+
}
|
|
42997
|
+
if (isAuthPopupUrl(url) || AUTH_SCHEMES.has(url.protocol)) return ALLOW;
|
|
42998
|
+
return deny(`the sign-in window may not navigate to ${url.protocol}`);
|
|
42999
|
+
}
|
|
43000
|
+
const STATIC_FRAME_PREFIX = "/v1/static/";
|
|
43001
|
+
function frameNavigationVerdict(input, trustedRendererUrls) {
|
|
43002
|
+
let url;
|
|
43003
|
+
try {
|
|
43004
|
+
url = new URL(input.url);
|
|
43005
|
+
} catch {
|
|
43006
|
+
return deny("not a URL");
|
|
43007
|
+
}
|
|
43008
|
+
if (input.isMainFrame) {
|
|
43009
|
+
return trustedRendererUrls.some(
|
|
43010
|
+
(trusted) => trustedDesktopFrame(input.url, trusted)
|
|
43011
|
+
) ? ALLOW : deny("the main window may only show the app's own document");
|
|
43012
|
+
}
|
|
43013
|
+
if (url.protocol === "blob:") {
|
|
43014
|
+
let minted;
|
|
43015
|
+
try {
|
|
43016
|
+
minted = new URL(url.pathname);
|
|
43017
|
+
} catch {
|
|
43018
|
+
return deny("blob: URL names no origin");
|
|
43019
|
+
}
|
|
43020
|
+
const own = trustedRendererUrls.some((trusted) => {
|
|
43021
|
+
try {
|
|
43022
|
+
const t = new URL(trusted);
|
|
43023
|
+
return t.protocol === "file:" ? minted.protocol === "file:" : minted.origin === t.origin;
|
|
43024
|
+
} catch {
|
|
43025
|
+
return false;
|
|
43026
|
+
}
|
|
43027
|
+
});
|
|
43028
|
+
return own ? ALLOW : deny("blob: minted by a document that is not the app");
|
|
43029
|
+
}
|
|
43030
|
+
if ((url.protocol === "http:" || url.protocol === "https:") && isLocalOrPrivateHost(url.hostname) && url.pathname.startsWith(STATIC_FRAME_PREFIX))
|
|
43031
|
+
return ALLOW;
|
|
43032
|
+
return deny(`a child frame may not navigate to ${url.protocol}`);
|
|
43033
|
+
}
|
|
43034
|
+
function permissionVerdict(query, trustedRendererUrls) {
|
|
43035
|
+
if (!query.isMainFrame) return false;
|
|
43036
|
+
if (!trustedRendererUrls.some(
|
|
43037
|
+
(trusted) => trustedDesktopFrame(query.requestingUrl, trusted)
|
|
43038
|
+
))
|
|
43039
|
+
return false;
|
|
43040
|
+
if (query.permission === "clipboard-sanitized-write" || query.permission === "fullscreen")
|
|
43041
|
+
return true;
|
|
43042
|
+
if (query.permission !== "media") return false;
|
|
43043
|
+
if (query.mediaTypes)
|
|
43044
|
+
return query.mediaTypes.length > 0 && query.mediaTypes.every((type2) => type2 === "audio");
|
|
43045
|
+
return query.mediaType === "audio";
|
|
43046
|
+
}
|
|
43047
|
+
function decodedPathname(pathname) {
|
|
43048
|
+
let current = pathname;
|
|
43049
|
+
for (let round = 0; round < 3; round += 1) {
|
|
43050
|
+
let next;
|
|
43051
|
+
try {
|
|
43052
|
+
next = decodeURIComponent(current);
|
|
43053
|
+
} catch {
|
|
43054
|
+
break;
|
|
43055
|
+
}
|
|
43056
|
+
if (next === current) break;
|
|
43057
|
+
current = next;
|
|
43058
|
+
}
|
|
43059
|
+
return current;
|
|
43060
|
+
}
|
|
43061
|
+
function isStaticServeRequest(rawUrl) {
|
|
43062
|
+
try {
|
|
43063
|
+
const url = new URL(rawUrl);
|
|
43064
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") return false;
|
|
43065
|
+
if (!isLocalOrPrivateHost(url.hostname)) return false;
|
|
43066
|
+
return decodedPathname(url.pathname).toLowerCase().startsWith(STATIC_FRAME_PREFIX);
|
|
43067
|
+
} catch {
|
|
43068
|
+
return false;
|
|
43069
|
+
}
|
|
43070
|
+
}
|
|
43071
|
+
const PREVIEW_CSP = [
|
|
43072
|
+
"default-src 'none'",
|
|
43073
|
+
"script-src 'unsafe-inline' 'unsafe-eval' https:",
|
|
43074
|
+
"style-src 'unsafe-inline' https:",
|
|
43075
|
+
"img-src data: blob: https:",
|
|
43076
|
+
"font-src data: https:",
|
|
43077
|
+
"media-src data: blob: https:",
|
|
43078
|
+
"connect-src https:",
|
|
43079
|
+
"worker-src blob:",
|
|
43080
|
+
"form-action 'none'",
|
|
43081
|
+
"base-uri 'none'"
|
|
43082
|
+
].join("; ");
|
|
43083
|
+
function withPreviewPolicy(headers) {
|
|
43084
|
+
const out = { ...headers };
|
|
43085
|
+
const existing = (name) => Object.keys(out).find((key) => key.toLowerCase() === name);
|
|
43086
|
+
const cspKey = existing("content-security-policy");
|
|
43087
|
+
if (cspKey) out[cspKey] = [...out[cspKey], PREVIEW_CSP];
|
|
43088
|
+
else out["Content-Security-Policy"] = [PREVIEW_CSP];
|
|
43089
|
+
if (!existing("x-content-type-options"))
|
|
43090
|
+
out["X-Content-Type-Options"] = ["nosniff"];
|
|
43091
|
+
return out;
|
|
43092
|
+
}
|
|
43093
|
+
function downloadVerdict(itemUrl, initiatorUrl, trustedRendererUrls) {
|
|
43094
|
+
if (!itemUrl.startsWith("blob:"))
|
|
43095
|
+
return deny("only the app's own blob: exports may write files");
|
|
43096
|
+
if (!trustedRendererUrls.some(
|
|
43097
|
+
(trusted) => trustedDesktopFrame(initiatorUrl, trusted)
|
|
43098
|
+
))
|
|
43099
|
+
return deny("the download was not started by one of the app's documents");
|
|
43100
|
+
return ALLOW;
|
|
43101
|
+
}
|
|
43102
|
+
function installNavigationVerdict(contents, decide, log2) {
|
|
43103
|
+
const onNavigation = (event) => {
|
|
43104
|
+
if (event.isSameDocument) return;
|
|
43105
|
+
const verdict = decide(event.url, event.isMainFrame);
|
|
43106
|
+
if (verdict.allowed) return;
|
|
43107
|
+
event.preventDefault();
|
|
43108
|
+
log2(
|
|
43109
|
+
`[window-guard] blocked ${event.isMainFrame ? "main-frame" : "child-frame"} navigation to ${event.url.slice(0, 200)}: ${verdict.reason}`
|
|
43110
|
+
);
|
|
43111
|
+
};
|
|
43112
|
+
contents.on("will-frame-navigate", onNavigation);
|
|
43113
|
+
contents.on("will-redirect", onNavigation);
|
|
43114
|
+
}
|
|
43115
|
+
function guardNavigation(contents, trustedUrls, log2) {
|
|
43116
|
+
installNavigationVerdict(
|
|
43117
|
+
contents,
|
|
43118
|
+
(url, isMainFrame) => frameNavigationVerdict({ url, isMainFrame }, trustedUrls()),
|
|
43119
|
+
log2
|
|
43120
|
+
);
|
|
43121
|
+
}
|
|
43122
|
+
function guardWindowOpen(contents, decide, openExternal, authWindowOptions, log2, notifyRefused) {
|
|
43123
|
+
contents.setWindowOpenHandler((details) => {
|
|
43124
|
+
const verdict = decide(details.url);
|
|
43125
|
+
if (verdict.action === "auth") {
|
|
43126
|
+
return {
|
|
43127
|
+
action: "allow",
|
|
43128
|
+
overrideBrowserWindowOptions: authWindowOptions
|
|
43129
|
+
};
|
|
43130
|
+
}
|
|
43131
|
+
if (verdict.action === "external") {
|
|
43132
|
+
void openExternal(verdict.url).then((outcome) => {
|
|
43133
|
+
if (!outcome.ok) notifyRefused?.(verdict.url, outcome.reason);
|
|
43134
|
+
});
|
|
43135
|
+
} else {
|
|
43136
|
+
log2(`[window-guard] denied window.open: ${verdict.reason}`);
|
|
43137
|
+
notifyRefused?.(details.url, verdict.reason);
|
|
43138
|
+
}
|
|
43139
|
+
return { action: "deny" };
|
|
43140
|
+
});
|
|
43141
|
+
contents.on("did-create-window", (window) => {
|
|
43142
|
+
guardPopupNavigation(window.webContents, log2);
|
|
43143
|
+
});
|
|
43144
|
+
}
|
|
43145
|
+
function guardPopupNavigation(contents, log2) {
|
|
43146
|
+
installNavigationVerdict(contents, (url) => popupNavigationVerdict(url), log2);
|
|
43147
|
+
contents.setWindowOpenHandler(() => {
|
|
43148
|
+
log2("[window-guard] denied window.open from the sign-in popup");
|
|
43149
|
+
return { action: "deny" };
|
|
43150
|
+
});
|
|
43151
|
+
}
|
|
43152
|
+
function guardPermissions(ses, trustedUrls, log2) {
|
|
43153
|
+
ses.setPermissionRequestHandler(
|
|
43154
|
+
(_contents, permission, callback, details) => {
|
|
43155
|
+
const granted = permissionVerdict(
|
|
43156
|
+
{
|
|
43157
|
+
permission,
|
|
43158
|
+
mediaTypes: "mediaTypes" in details ? details.mediaTypes ?? [] : void 0,
|
|
43159
|
+
isMainFrame: details.isMainFrame,
|
|
43160
|
+
requestingUrl: details.requestingUrl
|
|
43161
|
+
},
|
|
43162
|
+
trustedUrls()
|
|
43163
|
+
);
|
|
43164
|
+
if (!granted)
|
|
43165
|
+
log2(
|
|
43166
|
+
`[window-guard] denied permission request ${permission} from ${details.requestingUrl.slice(0, 200)}`
|
|
43167
|
+
);
|
|
43168
|
+
callback(granted);
|
|
43169
|
+
}
|
|
43170
|
+
);
|
|
43171
|
+
ses.setPermissionCheckHandler(
|
|
43172
|
+
(_contents, permission, _origin, details) => permissionVerdict(
|
|
43173
|
+
{
|
|
43174
|
+
permission,
|
|
43175
|
+
mediaType: details.mediaType,
|
|
43176
|
+
isMainFrame: details.isMainFrame,
|
|
43177
|
+
requestingUrl: details.requestingUrl ?? ""
|
|
43178
|
+
},
|
|
43179
|
+
trustedUrls()
|
|
43180
|
+
)
|
|
43181
|
+
);
|
|
43182
|
+
}
|
|
43183
|
+
function guardPreviewResponses(ses) {
|
|
43184
|
+
ses.webRequest.onHeadersReceived((details, callback) => {
|
|
43185
|
+
if (!isStaticServeRequest(details.url)) {
|
|
43186
|
+
callback({});
|
|
43187
|
+
return;
|
|
43188
|
+
}
|
|
43189
|
+
callback({
|
|
43190
|
+
responseHeaders: withPreviewPolicy(
|
|
43191
|
+
details.responseHeaders ?? {}
|
|
43192
|
+
)
|
|
43193
|
+
});
|
|
43194
|
+
});
|
|
43195
|
+
}
|
|
43196
|
+
function guardDownloads(ses, trustedUrls, log2) {
|
|
43197
|
+
ses.on("will-download", (event, item, webContents) => {
|
|
43198
|
+
const verdict = downloadVerdict(
|
|
43199
|
+
item.getURL(),
|
|
43200
|
+
webContents?.getURL() ?? "",
|
|
43201
|
+
trustedUrls()
|
|
43202
|
+
);
|
|
43203
|
+
if (verdict.allowed) return;
|
|
43204
|
+
event.preventDefault();
|
|
43205
|
+
log2(
|
|
43206
|
+
`[window-guard] blocked a download from ${item.getURL().slice(0, 200)}: ${verdict.reason}`
|
|
43207
|
+
);
|
|
43208
|
+
});
|
|
43209
|
+
}
|
|
42827
43210
|
const BASE64_FILE_EXTENSIONS = ["csv", "tsv", "xls", "xlsx", "ods"];
|
|
42828
43211
|
const resolveUserPath = (filePath, cwd) => resolveUserPath$1(filePath, cwd, electron.app.getPath("home"));
|
|
42829
43212
|
const windowLaunch = resolveWindowLaunchPlan({
|
|
@@ -43098,6 +43481,45 @@ const ownLaunchRequest = () => ({
|
|
|
43098
43481
|
show: windowLaunch.show,
|
|
43099
43482
|
trigger: "initial-present"
|
|
43100
43483
|
});
|
|
43484
|
+
const rendererDocumentUrl = () => process.env.ELECTRON_RENDERER_URL || node_url.pathToFileURL(path$1.join(__dirname, "../renderer/index.html")).href;
|
|
43485
|
+
const trustedRendererDocuments = () => [
|
|
43486
|
+
rendererDocumentUrl(),
|
|
43487
|
+
miniViewUrlFor(rendererDocumentUrl())
|
|
43488
|
+
];
|
|
43489
|
+
const openExternalVetted = (raw) => openVettedExternal(
|
|
43490
|
+
raw,
|
|
43491
|
+
(url) => electron.shell.openExternal(url),
|
|
43492
|
+
(message) => logger.warn(message, LogFileType.BACKEND)
|
|
43493
|
+
);
|
|
43494
|
+
const authPopupWindowOptions = {
|
|
43495
|
+
width: 800,
|
|
43496
|
+
height: 700,
|
|
43497
|
+
// Increased height for better visibility
|
|
43498
|
+
minWidth: 600,
|
|
43499
|
+
minHeight: 500,
|
|
43500
|
+
center: true,
|
|
43501
|
+
frame: true,
|
|
43502
|
+
autoHideMenuBar: false,
|
|
43503
|
+
backgroundColor: "#FFFFFF",
|
|
43504
|
+
webPreferences: {
|
|
43505
|
+
contextIsolation: true,
|
|
43506
|
+
nodeIntegration: false,
|
|
43507
|
+
webSecurity: true,
|
|
43508
|
+
allowRunningInsecureContent: false,
|
|
43509
|
+
sandbox: true,
|
|
43510
|
+
// Enable sandbox for additional security
|
|
43511
|
+
// Disable various features that aren't needed for auth
|
|
43512
|
+
enableWebSQL: false,
|
|
43513
|
+
navigateOnDragDrop: false,
|
|
43514
|
+
spellcheck: false,
|
|
43515
|
+
/*
|
|
43516
|
+
* A JS dialog in a popup must not be able to wedge it (round-2 S-7): a
|
|
43517
|
+
* renderer-reached `confirm()`/`alert()` needs no permission and blocks
|
|
43518
|
+
* every later evaluation on the page behind its modal.
|
|
43519
|
+
*/
|
|
43520
|
+
disableDialogs: true
|
|
43521
|
+
}
|
|
43522
|
+
};
|
|
43101
43523
|
function createWindow(initialSession = null, openCatalogue = false, request = ownLaunchRequest()) {
|
|
43102
43524
|
const chrome = resolveLaunchWindowChrome({
|
|
43103
43525
|
argv: process.argv,
|
|
@@ -43242,66 +43664,22 @@ function createWindow(initialSession = null, openCatalogue = false, request = ow
|
|
|
43242
43664
|
);
|
|
43243
43665
|
}, 1500);
|
|
43244
43666
|
});
|
|
43245
|
-
|
|
43246
|
-
|
|
43247
|
-
|
|
43248
|
-
|
|
43249
|
-
|
|
43250
|
-
|
|
43251
|
-
|
|
43252
|
-
|
|
43253
|
-
|
|
43254
|
-
|
|
43255
|
-
|
|
43256
|
-
|
|
43257
|
-
|
|
43258
|
-
|
|
43259
|
-
|
|
43260
|
-
|
|
43261
|
-
// Auth relay domains
|
|
43262
|
-
"storagerelay",
|
|
43263
|
-
// Special case for initial blank page
|
|
43264
|
-
"about:blank"
|
|
43265
|
-
];
|
|
43266
|
-
const isTrustedAuthDomain = (
|
|
43267
|
-
// Special case for about:blank which is used by MSAL to initialize the popup
|
|
43268
|
-
details.url === "about:blank" || // Check other trusted domains
|
|
43269
|
-
trustedAuthDomains.some(
|
|
43270
|
-
(domain) => url.hostname.includes(domain) || url.protocol.includes(domain) || // Special case for storage relay URLs
|
|
43271
|
-
details.url.startsWith("storagerelay:") || details.url.includes("storagerelay")
|
|
43272
|
-
)
|
|
43273
|
-
);
|
|
43274
|
-
if (isTrustedAuthDomain) {
|
|
43275
|
-
return {
|
|
43276
|
-
action: "allow",
|
|
43277
|
-
overrideBrowserWindowOptions: {
|
|
43278
|
-
width: 800,
|
|
43279
|
-
height: 700,
|
|
43280
|
-
// Increased height for better visibility
|
|
43281
|
-
minWidth: 600,
|
|
43282
|
-
minHeight: 500,
|
|
43283
|
-
center: true,
|
|
43284
|
-
frame: true,
|
|
43285
|
-
autoHideMenuBar: false,
|
|
43286
|
-
backgroundColor: "#FFFFFF",
|
|
43287
|
-
webPreferences: {
|
|
43288
|
-
contextIsolation: true,
|
|
43289
|
-
nodeIntegration: false,
|
|
43290
|
-
webSecurity: true,
|
|
43291
|
-
allowRunningInsecureContent: false,
|
|
43292
|
-
sandbox: true,
|
|
43293
|
-
// Enable sandbox for additional security
|
|
43294
|
-
// Disable various features that aren't needed for auth
|
|
43295
|
-
enableWebSQL: false,
|
|
43296
|
-
navigateOnDragDrop: false,
|
|
43297
|
-
spellcheck: false
|
|
43298
|
-
}
|
|
43299
|
-
}
|
|
43300
|
-
};
|
|
43301
|
-
}
|
|
43302
|
-
electron.shell.openExternal(details.url);
|
|
43303
|
-
return { action: "deny" };
|
|
43304
|
-
});
|
|
43667
|
+
guardNavigation(
|
|
43668
|
+
mainWindow2.webContents,
|
|
43669
|
+
trustedRendererDocuments,
|
|
43670
|
+
(m) => logger.warn(m, LogFileType.BACKEND)
|
|
43671
|
+
);
|
|
43672
|
+
guardWindowOpen(
|
|
43673
|
+
mainWindow2.webContents,
|
|
43674
|
+
popupVerdict,
|
|
43675
|
+
openExternalVetted,
|
|
43676
|
+
authPopupWindowOptions,
|
|
43677
|
+
(m) => logger.warn(m, LogFileType.BACKEND),
|
|
43678
|
+
(url, reason) => mainWindow2.webContents.send(EXTERNAL_OPEN_REFUSED_CHANNEL, {
|
|
43679
|
+
url,
|
|
43680
|
+
reason
|
|
43681
|
+
})
|
|
43682
|
+
);
|
|
43305
43683
|
if (utils.is.dev && process.env.ELECTRON_RENDERER_URL) {
|
|
43306
43684
|
mainWindow2.loadURL(process.env.ELECTRON_RENDERER_URL);
|
|
43307
43685
|
} else {
|
|
@@ -43340,8 +43718,8 @@ const reportBackendFailure = (message, fileType) => {
|
|
|
43340
43718
|
const reportRaise = (line) => {
|
|
43341
43719
|
logger.info(`[window-raise] ${line}`, LogFileType.BACKEND);
|
|
43342
43720
|
};
|
|
43343
|
-
function describeForwardedLaunch(profile,
|
|
43344
|
-
const named =
|
|
43721
|
+
function describeForwardedLaunch(profile, session2) {
|
|
43722
|
+
const named = session2 === null ? null : `the conversation it named (${session2})`;
|
|
43345
43723
|
const handed = named === null ? "it named no conversation" : `${named} rides with it`;
|
|
43346
43724
|
const effect = windowLaunch.show === "never" ? named === null ? `${handed}, so nothing is waiting to be opened, and it will not raise a window in the meantime` : `${handed}: the app will open it in the window it already has open, or in the next window it creates when that window is in use or there is none, and it will not raise a window in the meantime (up to ${PARKED_LAUNCH_LIMIT} conversations wait; an older one is dropped and logged)` : windowLaunch.show === "inactive" ? `${handed}; the app may order its window forward without activating it` : `${handed}; the app will raise its window`;
|
|
43347
43725
|
return `[second-instance] this launch did not start a window of its own: the app already open is the instance answering (profile: ${profile}), and this launch's window mode (${windowLaunch.mode}) was handed to it — ${effect}. Quit that app to start a fresh instance. Exiting.`;
|
|
@@ -43394,15 +43772,15 @@ function rendererArgumentFlags(initialSession, openCatalogue, chromeMode) {
|
|
|
43394
43772
|
}
|
|
43395
43773
|
const parkedLaunches = [];
|
|
43396
43774
|
const PARKED_LAUNCH_LIMIT = 16;
|
|
43397
|
-
function parkLaunch(
|
|
43398
|
-
parkedLaunches.push({ session, request });
|
|
43775
|
+
function parkLaunch(session2, request, why = "unreachable") {
|
|
43776
|
+
parkedLaunches.push({ session: session2, request });
|
|
43399
43777
|
const parkLine = {
|
|
43400
43778
|
trigger: request.trigger,
|
|
43401
43779
|
requester: request.requester,
|
|
43402
43780
|
report: reportRaise
|
|
43403
43781
|
};
|
|
43404
|
-
if (why === "in-use") reportParkedInUse(
|
|
43405
|
-
else reportParked(
|
|
43782
|
+
if (why === "in-use") reportParkedInUse(session2, request.show, parkLine);
|
|
43783
|
+
else reportParked(session2, parkLine, request.show);
|
|
43406
43784
|
if (parkedLaunches.length <= PARKED_LAUNCH_LIMIT) return;
|
|
43407
43785
|
const evicted = parkedLaunches.shift();
|
|
43408
43786
|
if (evicted) {
|
|
@@ -43460,12 +43838,12 @@ let openOwnWindow = null;
|
|
|
43460
43838
|
let attachBrowserHostToWindow = null;
|
|
43461
43839
|
const CONVERSATION_PAINT_FALLBACK_MS = 3e3;
|
|
43462
43840
|
const heldForConversation = /* @__PURE__ */ new Map();
|
|
43463
|
-
function holdPresentUntilConversation(window,
|
|
43841
|
+
function holdPresentUntilConversation(window, session2, request) {
|
|
43464
43842
|
const timer = setTimeout(() => {
|
|
43465
43843
|
releaseHeldWindow(window.id);
|
|
43466
43844
|
}, CONVERSATION_PAINT_FALLBACK_MS);
|
|
43467
43845
|
timer.unref?.();
|
|
43468
|
-
heldForConversation.set(window.id, { session, timer, request });
|
|
43846
|
+
heldForConversation.set(window.id, { session: session2, timer, request });
|
|
43469
43847
|
}
|
|
43470
43848
|
function releaseHeldWindow(windowId) {
|
|
43471
43849
|
const held = heldForConversation.get(windowId);
|
|
@@ -43482,9 +43860,9 @@ function releaseHeldWindow(windowId) {
|
|
|
43482
43860
|
}
|
|
43483
43861
|
return true;
|
|
43484
43862
|
}
|
|
43485
|
-
function releaseHeldWindowFor(
|
|
43863
|
+
function releaseHeldWindowFor(session2) {
|
|
43486
43864
|
for (const [windowId, held] of heldForConversation) {
|
|
43487
|
-
if (held.session !==
|
|
43865
|
+
if (held.session !== session2) continue;
|
|
43488
43866
|
releaseHeldWindow(windowId);
|
|
43489
43867
|
}
|
|
43490
43868
|
}
|
|
@@ -43564,8 +43942,8 @@ if (!gotTheLock) {
|
|
|
43564
43942
|
show: request.show,
|
|
43565
43943
|
argv: commandLine
|
|
43566
43944
|
}),
|
|
43567
|
-
openConversation: openConversationInWindow ? (
|
|
43568
|
-
|
|
43945
|
+
openConversation: openConversationInWindow ? (session2, request) => openConversationInWindow?.(
|
|
43946
|
+
session2,
|
|
43569
43947
|
secondInstanceRequest(request)
|
|
43570
43948
|
) : null,
|
|
43571
43949
|
/*
|
|
@@ -43584,8 +43962,8 @@ if (!gotTheLock) {
|
|
|
43584
43962
|
// WITH it, so the flush cannot re-derive it from argv that is gone, and
|
|
43585
43963
|
// the queue holds EVERY parked request rather than the last one
|
|
43586
43964
|
// (review round 2, MAJOR-1).
|
|
43587
|
-
queue: (
|
|
43588
|
-
parkLaunch(
|
|
43965
|
+
queue: (session2, request) => {
|
|
43966
|
+
parkLaunch(session2, secondInstanceRequest(request));
|
|
43589
43967
|
},
|
|
43590
43968
|
report: reportRaise
|
|
43591
43969
|
}
|
|
@@ -43595,6 +43973,17 @@ if (!gotTheLock) {
|
|
|
43595
43973
|
}
|
|
43596
43974
|
electron.app.whenReady().then(async () => {
|
|
43597
43975
|
utils.electronApp.setAppUserModelId("com.local-operator");
|
|
43976
|
+
guardPermissions(
|
|
43977
|
+
electron.session.defaultSession,
|
|
43978
|
+
trustedRendererDocuments,
|
|
43979
|
+
(m) => logger.warn(m, LogFileType.BACKEND)
|
|
43980
|
+
);
|
|
43981
|
+
guardPreviewResponses(electron.session.defaultSession);
|
|
43982
|
+
guardDownloads(
|
|
43983
|
+
electron.session.defaultSession,
|
|
43984
|
+
trustedRendererDocuments,
|
|
43985
|
+
(m) => logger.warn(m, LogFileType.BACKEND)
|
|
43986
|
+
);
|
|
43598
43987
|
if (process.env.LOCAL_OPERATOR_UI_SMOKE_TEST === "true") {
|
|
43599
43988
|
console.log(
|
|
43600
43989
|
`LOCAL_OPERATOR_UI_READY electron=${process.versions.electron}`
|
|
@@ -43698,7 +44087,7 @@ electron.app.whenReady().then(async () => {
|
|
|
43698
44087
|
} catch {
|
|
43699
44088
|
}
|
|
43700
44089
|
});
|
|
43701
|
-
const rendererUrl =
|
|
44090
|
+
const rendererUrl = rendererDocumentUrl();
|
|
43702
44091
|
const consoleCaptureUrl = consoleCaptureUrlFor(rendererUrl);
|
|
43703
44092
|
backendService.observeDesktopFeed(
|
|
43704
44093
|
(frame) => {
|
|
@@ -43785,7 +44174,7 @@ electron.app.whenReady().then(async () => {
|
|
|
43785
44174
|
windowMode: windowLaunch.mode
|
|
43786
44175
|
});
|
|
43787
44176
|
if (hotkeysAllowed(windowLaunch.mode) || miniViewExerciser) {
|
|
43788
|
-
|
|
44177
|
+
const quickSend = createMiniView({
|
|
43789
44178
|
url: miniViewUrlFor(rendererUrl),
|
|
43790
44179
|
preloadPath: path$1.join(__dirname, "../preload/index.js"),
|
|
43791
44180
|
show: windowLaunch.show,
|
|
@@ -43807,6 +44196,23 @@ electron.app.whenReady().then(async () => {
|
|
|
43807
44196
|
}).mode,
|
|
43808
44197
|
report: reportRaise
|
|
43809
44198
|
});
|
|
44199
|
+
miniView = quickSend;
|
|
44200
|
+
guardNavigation(
|
|
44201
|
+
quickSend.window.webContents,
|
|
44202
|
+
trustedRendererDocuments,
|
|
44203
|
+
(m) => logger.warn(m, LogFileType.BACKEND)
|
|
44204
|
+
);
|
|
44205
|
+
guardWindowOpen(
|
|
44206
|
+
quickSend.window.webContents,
|
|
44207
|
+
popupVerdict,
|
|
44208
|
+
openExternalVetted,
|
|
44209
|
+
authPopupWindowOptions,
|
|
44210
|
+
(m) => logger.warn(m, LogFileType.BACKEND),
|
|
44211
|
+
(url, reason) => quickSend.window.webContents.send(EXTERNAL_OPEN_REFUSED_CHANNEL, {
|
|
44212
|
+
url,
|
|
44213
|
+
reason
|
|
44214
|
+
})
|
|
44215
|
+
);
|
|
43810
44216
|
}
|
|
43811
44217
|
if (hotkeysAllowed(windowLaunch.mode)) {
|
|
43812
44218
|
const initial = readQuickSendValue();
|
|
@@ -44017,13 +44423,7 @@ electron.app.whenReady().then(async () => {
|
|
|
44017
44423
|
}
|
|
44018
44424
|
}
|
|
44019
44425
|
);
|
|
44020
|
-
electron.ipcMain.handle("open-external", async (_, url) =>
|
|
44021
|
-
try {
|
|
44022
|
-
await electron.shell.openExternal(url);
|
|
44023
|
-
} catch (error) {
|
|
44024
|
-
console.error("Error opening URL:", error);
|
|
44025
|
-
}
|
|
44026
|
-
});
|
|
44426
|
+
electron.ipcMain.handle("open-external", async (_, url) => openExternalVetted(url));
|
|
44027
44427
|
electron.ipcMain.handle(
|
|
44028
44428
|
"show-item-in-folder",
|
|
44029
44429
|
async (_, filePath) => {
|
|
@@ -44330,7 +44730,7 @@ electron.app.whenReady().then(async () => {
|
|
|
44330
44730
|
const windowId = mainWindow.webContents.id;
|
|
44331
44731
|
claimParkedFor(
|
|
44332
44732
|
mainWindow,
|
|
44333
|
-
(
|
|
44733
|
+
(session2, request2) => openSessionInWindow(session2, request2, { fromPark: true }),
|
|
44334
44734
|
parked
|
|
44335
44735
|
);
|
|
44336
44736
|
claimParkedConsentAttention(mainWindow);
|