/* Sovran_SystemsOS Hub — Shared domain and router instructions. This is the single source of truth for the simple setup guidance shown in: • First-boot onboarding for Server + Desktop • Feature setup in the Hub • Domain reconfiguration and troubleshooting Keep the wording consistent by editing it here. */ "use strict"; function dpEsc(str) { return String(str) .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } /* Explain only what the user needs for the step in front of them. */ function renderDomainNeedsHtml(opts) { opts = opts || {}; var serviceName = opts.serviceName || null; var purpose = opts.purpose || ""; var html = ""; if (purpose === "btcpay") { html += "

Put your BTCPay Server online

"; html += "

Let people donate Bitcoin, pay you, or visit your online store.

"; html += "

BTCPay Server needs a domain so people can reach it. " + "Sovran_SystemsOS walks you through getting your domain from " + 'Njal.la' + " and connecting it. Just follow the steps below.

"; } else if (serviceName) { html += "

To make " + dpEsc(serviceName) + " available outside your home, it needs a domain.

"; html += "

Sovran_SystemsOS walks you through getting your domain from " + 'Njal.la' + " and connecting it. Just follow the steps below.

"; } else { html += "

Your domain is the address people use to reach your services on the internet.

"; html += "

Sovran_SystemsOS walks you through getting your domain from " + 'Njal.la' + " and connecting your services. Just follow the steps below.

"; } return html; } /* The shortest Njal.la steps that still tell the user exactly what to do. */ function renderNjallaStepsHtml(opts) { var hostExample = dpEsc((opts && opts.hostExample) || "call"); var pasteHint = (opts && opts.pasteHint) || "below"; var html = ""; html += '

Get and connect your domain:

'; html += '
    '; html += '
  1. Open Njal.la, create an account, and get a domain.
  2. '; html += "
  3. Open your domain and add a Dynamic record for this service. " + "In the Name box, enter only the first part of the address. " + "For " + hostExample + ".yourdomain.com, enter " + hostExample + ". " + "If you are using the whole domain, leave the box blank or enter @.
  4. "; html += "
  5. Copy the update command Njal.la gives you and paste it " + pasteHint + ".
  6. "; html += "
"; return html; } /* One router task shared by all normal domain-based services. */ function renderRouterPortsHtml(opts) { opts = opts || {}; var ipPart = opts.internalIp ? " to this computer at " + dpEsc(opts.internalIp) + "" : " to this computer"; var html = ""; html += "🔌 One router task: in your router’s Port Forwarding settings, " + "forward 80 (TCP) and 443 (TCP)" + ipPart + ". If your router asks for outside and inside port numbers, use the same number for both. " + "You only need to do this once. All your services share these two ports."; if (opts.extraNote) { html += " " + dpEsc(opts.extraNote); } return html; } /* Show generic wording immediately, then add the computer's address when found. */ function renderRouterPortsBox(elId, opts) { var el = document.getElementById(elId); if (!el) return; el.innerHTML = renderRouterPortsHtml(opts || {}); fetch("/api/network") .then(function(r) { return r.json(); }) .then(function(data) { var target = document.getElementById(elId); if (!target) return; var ip = data && data.internal_ip; if (ip && ip !== "unavailable") { var next = {}; for (var k in (opts || {})) next[k] = opts[k]; next.internalIp = String(ip).trim(); target.innerHTML = renderRouterPortsHtml(next); } }) .catch(function() { /* Generic wording is already shown. */ }); }