updates to server tunnels
CI / Build & Test (push) Successful in 2m45s

This commit is contained in:
Raven Scott
2026-02-28 21:47:40 -05:00
parent f5a299b9ec
commit 6c1428c6f1
4 changed files with 57 additions and 14 deletions
+4
View File
@@ -1596,6 +1596,10 @@
</div>
<div class="modal-body">
<p class="modal-desc">Expose a local port as an hs:// tunnel. The generated URL can be shared with others.</p>
<div class="form-group">
<label class="form-label" for="startServerLabel">Label <span style="color:var(--text4);font-weight:400;">(optional)</span></label>
<input type="text" id="startServerLabel" class="input" placeholder="e.g. My Web App" autocomplete="off">
</div>
<div class="row">
<div class="form-group" style="max-width:120px;">
<label class="form-label" for="startServerPort">Port</label>
+44 -10
View File
@@ -1333,10 +1333,11 @@ function initOvLists() {
searchId: 'ovServersSearch', subtitleId: 'ovServersSubtitle',
cols: 3, emptyMsg: 'No server tunnels',
rowFn: s => {
const key = s.hsUrl || '';
const key = s.url || s.hsUrl || '';
const short = key.length > 22 ? key.slice(0, 9) + '…' + key.slice(-7) : key;
const display = s.label ? escapeHtml(s.label) : `<span class="mono" style="font-size:11px;color:var(--text3);">${escapeHtml(String(s.port || '—'))}</span>`;
return `<tr>
<td class="mono" style="font-size:12px;">${escapeHtml(String(s.port || '—'))}</td>
<td style="font-size:12px;">${display}</td>
<td>${stateTag(s.state)}</td>
<td class="mono" style="font-size:11px;color:var(--text3);"
title="${escapeHtml(key)}">${escapeHtml(short)}</td>
@@ -1378,7 +1379,25 @@ function initOvLists() {
// Quick action buttons → open existing modals directly
$('qaAddVhost') ?.addEventListener('click', () => openModal('modal-addVhost'));
$('qaAddServer') ?.addEventListener('click', () => openModal('modal-startServer'));
$('qaAddServer')?.addEventListener('click', () => {
const editIdEl = $('serverEditId');
if (editIdEl) editIdEl.value = '';
const labelEl = $('startServerLabel');
if (labelEl) labelEl.value = '';
const portEl = $('startServerPort');
if (portEl) portEl.value = '3000';
const hostEl = $('startServerHost');
if (hostEl) hostEl.value = '127.0.0.1';
const secureEl = $('startServerSecure');
if (secureEl) secureEl.checked = true;
const tcpEl = $('startServerProtocolTcp');
if (tcpEl) tcpEl.checked = true;
const titleEl = $('modal-startServer-title');
if (titleEl) titleEl.textContent = 'Start Server Tunnel';
const submitEl = $('startServerSubmit');
if (submitEl) submitEl.textContent = 'Start Server';
openModal('modal-startServer');
});
$('qaAddSvc') ?.addEventListener('click', () => openModal('modal-addServiceTunnel'));
$('qaAddSsh') ?.addEventListener('click', () => openAddSshModal(null));
$('qaAddRdp') ?.addEventListener('click', () => openAddRdpModal(null));
@@ -1589,9 +1608,13 @@ function updateSwarmsTable(state) {
const id = s.id || s.serverId || '';
const url = s.url || s.hsUrl || '';
const safeId = id.replace(/"/g, '&quot;');
const label = s.label || '';
return `
<tr>
<td class="mono" style="font-size:11px;color:var(--text3);">${escapeHtml(truncate(id, 20))}</td>
<td>
${label ? `<div style="font-weight:600;color:var(--text);margin-bottom:2px;">${escapeHtml(label)}</div>` : ''}
<div class="mono" style="font-size:11px;color:var(--text3);">${escapeHtml(truncate(id, 20))}</div>
</td>
<td style="font-weight:600;color:var(--text);">${s.port ?? '—'}</td>
<td>
<div style="display:flex;align-items:center;gap:6px;">
@@ -1630,9 +1653,11 @@ function updateSwarmsTable(state) {
const server = (state.servers || []).find(s => (s.id || s.serverId) === serverId);
if (!server) return;
$('serverEditId').value = serverId;
const labelEl = $('startServerLabel');
const portEl = $('startServerPort');
const hostEl = $('startServerHost');
const secureEl = $('startServerSecure');
if (labelEl) labelEl.value = server.label || '';
if (portEl) portEl.value = server.port ?? 3000;
if (hostEl) hostEl.value = server.host ?? '127.0.0.1';
if (secureEl) secureEl.checked = server.secure !== false;
@@ -2047,15 +2072,22 @@ function setupEvents() {
// ── Start Server ────────────────────────────────────────────────────────
$('startServerBtn')?.addEventListener('click', () => {
// Reset to "new server" mode
const editIdEl = $('serverEditId');
if (editIdEl) editIdEl.value = '';
const labelEl = $('startServerLabel');
if (labelEl) labelEl.value = '';
const portEl = $('startServerPort');
if (portEl) portEl.value = '3000';
const hostEl = $('startServerHost');
if (hostEl) hostEl.value = '127.0.0.1';
const secureEl = $('startServerSecure');
if (secureEl) secureEl.checked = true;
const tcpEl = $('startServerProtocolTcp');
if (tcpEl) tcpEl.checked = true;
const titleEl = $('modal-startServer-title');
if (titleEl) titleEl.textContent = 'Start Server Tunnel';
const submitEl = $('startServerSubmit');
if (submitEl) submitEl.textContent = 'Start Server';
const tcpEl = $('startServerProtocolTcp');
if (tcpEl) tcpEl.checked = true;
openModal('modal-startServer');
});
@@ -2063,18 +2095,21 @@ function setupEvents() {
const portEl = $('startServerPort');
const hostEl = $('startServerHost');
const secureEl = $('startServerSecure');
const labelEl = $('startServerLabel');
const editIdEl = $('serverEditId');
const port = parseInt(portEl?.value, 10) || 3000;
const host = (hostEl?.value || '127.0.0.1').trim();
const secure = secureEl?.checked !== false;
const udp = document.querySelector('input[name="startServerProtocol"]:checked')?.value === 'udp';
const editId = ($('serverEditId')?.value || '').trim();
const label = (labelEl?.value || '').trim();
const editId = (editIdEl?.value || '').trim();
if (!port || port < 1 || port > 65535) { showModalError('modal-startServer', 'startServerError', 'Port must be 165535'); return; }
const btn = $('startServerSubmit');
if (btn) { btn.disabled = true; btn.textContent = editId ? 'Saving…' : 'Starting…'; }
const doStart = () => {
chrome.runtime.sendMessage(
{ target: 'holesail-native', action: 'send', payload: { type: 'startServer', payload: { port, host, secure, udp } } },
{ target: 'holesail-native', action: 'send', payload: { type: 'startServer', payload: { port, host, secure, udp, label } } },
(response) => {
if (btn) { btn.disabled = false; btn.textContent = editId ? 'Save Changes' : 'Start Server'; }
if (response?.ok) {
@@ -2090,7 +2125,6 @@ function setupEvents() {
};
if (editId) {
// Stop old server first, then start new one with updated settings
chrome.runtime.sendMessage(
{ target: 'holesail-native', action: 'send', payload: { type: 'stopServer', payload: { serverId: editId } } },
() => doStart()
+7 -3
View File
@@ -86,7 +86,7 @@ function saveStateSync() {
const file = getStatePath();
const serversList = [];
for (const [id, s] of servers) {
serversList.push({ id, port: s.port, host: s.host, secure: s.secure, udp: s.udp || false });
serversList.push({ id, port: s.port, host: s.host, secure: s.secure, udp: s.udp || false, label: s.label || '' });
}
const virtualHostsList = [];
for (const [hostname, v] of virtualHosts) {
@@ -309,8 +309,9 @@ async function startServer(payload) {
const host = payload.host || '127.0.0.1';
const secure = payload.secure !== false;
const udp = payload.udp === true;
const label = (payload.label || '').trim();
const serverId = useServerId(payload.serverId);
debugLog('startServer: serverId=', serverId, 'port=', port, 'host=', host, 'secure=', secure, 'udp=', udp);
debugLog('startServer: serverId=', serverId, 'port=', port, 'host=', host, 'secure=', secure, 'udp=', udp, 'label=', label);
if (servers.has(serverId)) {
debugLog('startServer: serverId already in use');
return { ok: false, error: 'Server id already in use' };
@@ -325,6 +326,7 @@ async function startServer(payload) {
host: hs.info.host,
secure,
udp,
label,
url,
createdAt: Date.now()
});
@@ -337,7 +339,8 @@ async function startServer(payload) {
port: hs.info.port,
host: hs.info.host,
secure,
udp
udp,
label
};
} catch (e) {
debugLog('startServer: error', e.message);
@@ -372,6 +375,7 @@ function getServers() {
url: s.url,
secure: s.secure,
udp: s.udp || false,
label: s.label || '',
createdAt: s.createdAt
});
}
+2 -1
View File
@@ -107,7 +107,8 @@ async function restorePersistedTunnels(restored) {
port: s.port,
host: s.host || '127.0.0.1',
secure: s.secure !== false,
udp: s.udp === true
udp: s.udp === true,
label: s.label || ''
});
if (result.ok) serverOk++;
else serverFail++;