Security Fixes

This commit is contained in:
Andy Dixon
2026-06-16 09:41:51 +01:00
parent 9bbd9ceccf
commit fcb19c96c8
22 changed files with 1578 additions and 134 deletions
+80 -2
View File
@@ -744,7 +744,7 @@
* Opens a new session for the given profile ID.
* @param {string} profileId
*/
async connectProfile(profileId) {
async connectProfile(profileId, options = {}) {
const profile = this.state.getProfile(profileId);
if (!profile) {
this.notifications.error("Profile not found");
@@ -774,6 +774,14 @@
if (decision !== "new") return;
}
if (
!options.skipDirectVNCWarning &&
this._requiresDirectVNCWarning(profile)
) {
const ok = await this.confirmDirectVNCProfile(profile, "connect");
if (!ok) return;
}
try {
const sessionInfo =
await window.go.api.Service.ConnectSession(profileId);
@@ -977,7 +985,9 @@
*/
_confirmReuseSession(profile, session) {
const createElement = window.NexusTerminal.createElement;
const label = (profile.displayName || profile.host || "Untitled").trim();
const label = window.NexusTerminal.escapeHtml(
(profile.displayName || profile.host || "Untitled").trim(),
);
const stateLabel =
session.state === "connected" ? "connected" : "connecting";
@@ -1033,6 +1043,74 @@
});
}
/**
* Reports whether a profile connects directly to VNC without SSH tunnelling.
* @param {Object} profile
* @returns {boolean}
* @private
*/
_requiresDirectVNCWarning(profile) {
return !!(
profile &&
profile.protocol === "vnc" &&
profile.vnc &&
!profile.vnc.sshTunnel
);
}
/**
* Warns before saving or connecting direct VNC profiles.
* @param {Object} profile
* @param {"save"|"connect"} action
* @returns {Promise<boolean>}
*/
confirmDirectVNCProfile(profile, action) {
const { createElement, createModalShell } = window.NexusTerminal;
const label = (
profile.displayName ||
profile.vnc?.vncHost ||
profile.host ||
"VNC"
).trim();
const actionLabel = action === "connect" ? "Connect" : "Save";
return new Promise((resolve) => {
const shell = createModalShell("Direct VNC Connection", "modal-sm");
const bodyText = createElement("p", "", {
textContent:
label +
" is configured without an SSH tunnel. VNC traffic may be visible to the network unless the server is otherwise protected.",
});
bodyText.style.fontSize = "var(--text-sm)";
bodyText.style.color = "var(--text-secondary)";
shell.body.appendChild(bodyText);
const cancelBtn = createElement("button", "btn btn-sm", {
textContent: "Cancel",
});
const okBtn = createElement(
"button",
"btn btn-sm btn-warning direct-vnc-confirm",
{ textContent: actionLabel },
);
shell.footer.appendChild(cancelBtn);
shell.footer.appendChild(okBtn);
const close = (value) => {
shell.remove();
resolve(value);
};
shell.closeButton.addEventListener("click", () => close(false));
cancelBtn.addEventListener("click", () => close(false));
okBtn.addEventListener("click", () => close(true));
shell.backdrop.addEventListener("click", (e) => {
if (e.target === shell.backdrop) close(false);
});
shell.show();
});
}
// ── Import / Export ──────────────────────────────────────────────
/**