11<!doctype html>
22< html lang ="en ">
3+
34< head >
45 < meta charset ="utf-8 " />
56 < meta name ="viewport " content ="width=device-width, initial-scale=1 " />
67 < title > Tailrelay</ title >
78 < link rel ="stylesheet " href ="/static/vendor/bootstrap/css/bootstrap.min.css " />
89 < link rel ="stylesheet " href ="/static/css/spa.css " />
910</ head >
11+
1012< body class ="bg-body-tertiary ">
1113 < nav class ="navbar navbar-expand-lg border-bottom ">
1214 < div class ="container-fluid ">
1315 < span class ="navbar-brand fw-semibold "> Tailrelay</ span >
1416 < div class ="d-flex align-items-center gap-2 ">
1517 < button id ="theme-toggle " class ="btn btn-sm btn-outline-secondary " aria-label ="Toggle theme ">
16- < svg class ="bi " aria-hidden ="true "> < use href ="/static/vendor/bootstrap-icons/bootstrap-icons.svg#bi-circle-half "> </ use > </ svg >
18+ < svg class ="bi " aria-hidden ="true ">
19+ < use href ="/static/vendor/bootstrap-icons/bootstrap-icons.svg#bi-circle-half "> </ use >
20+ </ svg >
1721 </ button >
1822 < button id ="refresh " class ="btn btn-sm btn-outline-secondary ">
19- < svg class ="bi me-1 " aria-hidden ="true "> < use href ="/static/vendor/bootstrap-icons/bootstrap-icons.svg#bi-arrow-clockwise "> </ use > </ svg >
23+ < svg class ="bi me-1 " aria-hidden ="true ">
24+ < use href ="/static/vendor/bootstrap-icons/bootstrap-icons.svg#bi-arrow-clockwise "> </ use >
25+ </ svg >
2026 Refresh
2127 </ button >
2228 </ div >
2935 < h1 class ="h4 mb-1 "> Relays & Proxies</ h1 >
3036 </ div >
3137 < div class ="d-flex align-items-center gap-2 ">
32- < button class ="btn btn-sm btn-outline-secondary " data-bs-toggle ="collapse " data-bs-target ="#help-section " aria-expanded ="false " aria-controls ="help-section ">
33- < svg class ="bi me-1 " aria-hidden ="true "> < use href ="/static/vendor/bootstrap-icons/bootstrap-icons.svg#bi-question-circle "> </ use > </ svg >
38+ < button class ="btn btn-sm btn-outline-secondary " data-bs-toggle ="collapse " data-bs-target ="#help-section "
39+ aria-expanded ="false " aria-controls ="help-section ">
40+ < svg class ="bi me-1 " aria-hidden ="true ">
41+ < use href ="/static/vendor/bootstrap-icons/bootstrap-icons.svg#bi-question-circle "> </ use >
42+ </ svg >
3443 Help
3544 </ button >
36- < span class ="text-muted small "> Show/Hide:</ span >
3745 < div class ="btn-group " role ="group " aria-label ="Type filter ">
3846 < input type ="checkbox " class ="btn-check " id ="filter-relay " autocomplete ="off " checked />
39- < label class ="btn btn-outline-primary btn-sm " for ="filter-relay " data-bs-toggle ="tooltip " data-bs-placement ="bottom " title ="TCP relays served by socat ">
40- < svg class ="bi me-1 " aria-hidden ="true "> < use href ="/static/vendor/bootstrap-icons/bootstrap-icons.svg#bi-diagram-3 "> </ use > </ svg >
47+ < label class ="btn btn-outline-primary btn-sm " for ="filter-relay " data-bs-toggle ="tooltip "
48+ data-bs-placement ="bottom " title ="TCP relays served by socat ">
49+ < svg class ="bi me-1 " aria-hidden ="true ">
50+ < use href ="/static/vendor/bootstrap-icons/bootstrap-icons.svg#bi-diagram-3 "> </ use >
51+ </ svg >
4152 Relays
4253 </ label >
4354 < input type ="checkbox " class ="btn-check " id ="filter-proxy " autocomplete ="off " checked />
44- < label class ="btn btn-outline-primary btn-sm " for ="filter-proxy " data-bs-toggle ="tooltip " data-bs-placement ="bottom " title ="HTTPS reverse proxies served by Caddy ">
45- < svg class ="bi me-1 " aria-hidden ="true "> < use href ="/static/vendor/bootstrap-icons/bootstrap-icons.svg#bi-shield-lock "> </ use > </ svg >
55+ < label class ="btn btn-outline-primary btn-sm " for ="filter-proxy " data-bs-toggle ="tooltip "
56+ data-bs-placement ="bottom " title ="HTTPS reverse proxies served by Caddy ">
57+ < svg class ="bi me-1 " aria-hidden ="true ">
58+ < use href ="/static/vendor/bootstrap-icons/bootstrap-icons.svg#bi-shield-lock "> </ use >
59+ </ svg >
4660 Proxies
4761 </ label >
4862 </ div >
@@ -53,12 +67,17 @@ <h1 class="h4 mb-1">Relays & Proxies</h1>
5367 < div class ="card ">
5468 < div class ="card-body ">
5569 < h2 class ="h6 mb-2 "> About Tailrelay</ h2 >
56- < p class ="mb-3 "> Manage TCP relays and HTTPS proxies in one place. Tailrelay combines Tailscale, Caddy, and socat to expose local services securely to your Tailnet.</ p >
57-
70+ < p class ="mb-3 "> Manage TCP relays and HTTPS proxies in one place. Tailrelay combines Tailscale, Caddy, and
71+ socat to expose local services securely to your Tailnet.</ p >
72+
5873 < h2 class ="h6 mb-2 "> MagicDNS Requirement</ h2 >
59- < p class ="mb-2 "> Enable MagicDNS in the < a href ="https://login.tailscale.com/admin/dns " target ="_blank " rel ="noopener "> Tailscale DNS settings</ a > . Tailnets created on or after October 20, 2022 have MagicDNS enabled by default.</ p >
74+ < p class ="mb-2 "> Enable MagicDNS in the < a href ="https://login.tailscale.com/admin/dns " target ="_blank "
75+ rel ="noopener "> Tailscale DNS settings</ a > . Tailnets created on or after October 20, 2022 have MagicDNS
76+ enabled by default.</ p >
6077 < p class ="mb-0 small text-muted ">
61- < svg class ="bi me-1 " aria-hidden ="true "> < use href ="/static/vendor/bootstrap-icons/bootstrap-icons.svg#bi-info-circle "> </ use > </ svg >
78+ < svg class ="bi me-1 " aria-hidden ="true ">
79+ < use href ="/static/vendor/bootstrap-icons/bootstrap-icons.svg#bi-info-circle "> </ use >
80+ </ svg >
6281 < a href ="https://tailscale.com/kb/1081/magicdns " target ="_blank " rel ="noopener "> Learn how MagicDNS works</ a >
6382 </ p >
6483 </ div >
@@ -87,9 +106,14 @@ <h2 class="h6 mb-2">MagicDNS Requirement</h2>
87106 < option value ="WARN "> WARN</ option >
88107 < option value ="ERROR "> ERROR</ option >
89108 </ select >
90- < button id ="clear-logs " class ="btn btn-sm btn-outline-secondary "> Clear</ button >
91- < button class ="btn btn-sm btn-outline-primary " data-bs-toggle ="collapse " data-bs-target ="#log-console " aria-expanded ="false " aria-controls ="log-console ">
92- Toggle Console
109+ < button id ="clear-logs " class ="btn btn-sm btn-outline-secondary ">
110+ < svg class ="bi me-1 " aria-hidden ="true "> < use href ="/static/vendor/bootstrap-icons/bootstrap-icons.svg#bi-x-lg "> </ use > </ svg >
111+ Clear
112+ </ button >
113+ < button class ="btn btn-sm btn-outline-primary " data-bs-toggle ="collapse " data-bs-target ="#log-console "
114+ aria-expanded ="false " aria-controls ="log-console ">
115+ < svg class ="bi me-1 " aria-hidden ="true "> < use href ="/static/vendor/bootstrap-icons/bootstrap-icons.svg#bi-terminal "> </ use > </ svg >
116+ Console
93117 </ button >
94118 </ div >
95119 </ div >
@@ -103,18 +127,25 @@ <h2 class="h6 mb-2">MagicDNS Requirement</h2>
103127
104128 <!-- Floating Action Button -->
105129 < div class ="fab-container ">
106- < button id ="fab-button " class ="btn btn-primary fab rounded-circle shadow-lg " type ="button " data-bs-toggle ="dropdown " aria-expanded ="false ">
107- < svg class ="bi " style ="width: 1.5em; height: 1.5em; " aria-hidden ="true "> < use href ="/static/vendor/bootstrap-icons/bootstrap-icons.svg#bi-plus-lg "> </ use > </ svg >
130+ < button id ="fab-button " class ="btn btn-primary fab rounded-circle shadow-lg " type ="button " data-bs-toggle ="dropdown "
131+ aria-expanded ="false ">
132+ < svg class ="bi " style ="width: 1.5em; height: 1.5em; " aria-hidden ="true ">
133+ < use href ="/static/vendor/bootstrap-icons/bootstrap-icons.svg#bi-plus-lg "> </ use >
134+ </ svg >
108135 </ button >
109136 < ul class ="dropdown-menu dropdown-menu-end fab-menu ">
110137 < li > < a id ="add-relay-btn " class ="dropdown-item " href ="# ">
111- < svg class ="bi me-2 " aria-hidden ="true "> < use href ="/static/vendor/bootstrap-icons/bootstrap-icons.svg#bi-diagram-3 "> </ use > </ svg >
112- Add Relay
113- </ a > </ li >
138+ < svg class ="bi me-2 " aria-hidden ="true ">
139+ < use href ="/static/vendor/bootstrap-icons/bootstrap-icons.svg#bi-diagram-3 "> </ use >
140+ </ svg >
141+ Add Relay
142+ </ a > </ li >
114143 < li > < a id ="add-proxy-btn " class ="dropdown-item " href ="# ">
115- < svg class ="bi me-2 " aria-hidden ="true "> < use href ="/static/vendor/bootstrap-icons/bootstrap-icons.svg#bi-shield-lock "> </ use > </ svg >
116- Add Proxy
117- </ a > </ li >
144+ < svg class ="bi me-2 " aria-hidden ="true ">
145+ < use href ="/static/vendor/bootstrap-icons/bootstrap-icons.svg#bi-shield-lock "> </ use >
146+ </ svg >
147+ Add Proxy
148+ </ a > </ li >
118149 </ ul >
119150 </ div >
120151
@@ -131,17 +162,20 @@ <h5 class="modal-title" id="relayModalLabel">Add Relay</h5>
131162 < input type ="hidden " id ="relay-id " />
132163 < div class ="mb-3 ">
133164 < label for ="relay-listen-port " class ="form-label "> Listen Port</ label >
134- < input type ="number " class ="form-control " id ="relay-listen-port " required min ="1 " max ="65535 " placeholder ="e.g., 8080 ">
165+ < input type ="number " class ="form-control " id ="relay-listen-port " required min ="1 " max ="65535 "
166+ placeholder ="e.g., 8080 ">
135167 < div class ="form-text "> Port on which the relay will listen on your Tailnet</ div >
136168 </ div >
137169 < div class ="mb-3 ">
138170 < label for ="relay-target-host " class ="form-label "> Target Host</ label >
139- < input type ="text " class ="form-control " id ="relay-target-host " required placeholder ="e.g., localhost or 192.168.1.100 ">
171+ < input type ="text " class ="form-control " id ="relay-target-host " required
172+ placeholder ="e.g., localhost or 192.168.1.100 ">
140173 < div class ="form-text "> Hostname or IP address of the target service</ div >
141174 </ div >
142175 < div class ="mb-3 ">
143176 < label for ="relay-target-port " class ="form-label "> Target Port</ label >
144- < input type ="number " class ="form-control " id ="relay-target-port " required min ="1 " max ="65535 " placeholder ="e.g., 3000 ">
177+ < input type ="number " class ="form-control " id ="relay-target-port " required min ="1 " max ="65535 "
178+ placeholder ="e.g., 3000 ">
145179 < div class ="form-text "> Port on which the target service is listening</ div >
146180 </ div >
147181 < div class ="form-check ">
@@ -171,26 +205,27 @@ <h5 class="modal-title" id="proxyModalLabel">Add Proxy</h5>
171205 < div class ="modal-body ">
172206 < form id ="proxyForm ">
173207 < input type ="hidden " id ="proxy-id " />
174- < div class ="mb-3 ">
175- < label for ="proxy-hostname " class ="form-label "> Hostname</ label >
176- < input type ="text " class ="form-control " id ="proxy-hostname " required placeholder ="e.g., myservice ">
177- < div class ="form-text "> Tailscale hostname (without domain - will use your Tailnet FQDN)</ div >
178- </ div >
179208 < div class ="mb-3 ">
180209 < label for ="proxy-port " class ="form-label "> Port (Optional)</ label >
181- < input type ="number " class ="form-control " id ="proxy-port " min ="1 " max ="65535 " placeholder ="Leave empty for default HTTPS (443) ">
210+ < input type ="number " class ="form-control " id ="proxy-port " min ="1 " max ="65535 "
211+ placeholder ="Leave empty for default HTTPS (443) ">
182212 < div class ="form-text "> Custom port for the proxy (optional, defaults to 443)</ div >
183213 </ div >
184214 < div class ="mb-3 ">
185215 < label for ="proxy-target " class ="form-label "> Target</ label >
186- < input type ="text " class ="form-control " id ="proxy-target " required placeholder ="e.g., http://localhost:3000 ">
216+ < input type ="text " class ="form-control " id ="proxy-target " required
217+ placeholder ="e.g., http://localhost:3000 ">
187218 < div class ="form-text "> Backend URL to proxy requests to</ div >
188219 </ div >
189- < div class ="form-check mb-2 ">
190- < input class ="form-check-input " type ="checkbox " id ="proxy-tls ">
191- < label class ="form-check-label " for ="proxy-tls ">
192- Enable TLS termination
193- </ label >
220+ < div class ="mb-3 ">
221+ < label for ="proxy-tls-cert " class ="form-label "> TLS Certificate (Optional)</ label >
222+ < input type ="file " class ="form-control " id ="proxy-tls-cert " accept =".pem,.crt,.cer ">
223+ < div class ="form-text "> Upload TLS certificate for backend HTTPS connections</ div >
224+ < div id ="proxy-tls-cert-current " class ="d-flex align-items-center gap-2 mt-2 "
225+ style ="display: none !important; ">
226+ < span class ="badge text-bg-success "> Current: < span id ="proxy-tls-cert-filename "> </ span > </ span >
227+ < button type ="button " class ="btn btn-sm btn-outline-danger " id ="proxy-tls-cert-remove "> Remove</ button >
228+ </ div >
194229 </ div >
195230 < div class ="form-check mb-2 ">
196231 < input class ="form-check-input " type ="checkbox " id ="proxy-trusted-proxies ">
@@ -236,4 +271,5 @@ <h5 class="modal-title" id="deleteModalLabel">Confirm Delete</h5>
236271 < script src ="/static/vendor/bootstrap/js/bootstrap.bundle.min.js "> </ script >
237272 < script src ="/static/js/spa.bundle.js " defer > </ script >
238273</ body >
239- </ html >
274+
275+ </ html >
0 commit comments