Files
web-vnc/internal/server/template.go
T
Codex b89477fb87 feat: web-vnc single-binary browser VNC gateway with password access
- Go stdlib-only gateway: serves noVNC client, password auth, WS<->TCP relay
- auth: PBKDF2-HMAC-SHA256 password hash, HMAC session cookies, login rate limit
- relay: hand-written RFC 6455 WebSocket + transparent RFB bridge
- vncspawner: cross-OS VNC server detection/launch (Windows/Linux/macOS)
- server: /login /logout /vnc /api/status routes, session middleware, embed.FS
- scripts: get-novnc, get-vnc (zip-verified), list-ips, open-firewall
- run.bat: one-click launcher (asks only password), lists access IPs
- README/AGENTS.md (Russian), .gitignore (root-anchored binaries)
2026-07-30 17:40:31 +03:00

40 lines
1.8 KiB
Go

package server
import (
"html/template"
"net/http"
)
type htmlTemplate = template.Template
func mustParseLoginTemplate() *htmlTemplate {
return template.Must(template.New("login").Parse(loginPageHTML))
}
func (s *Server) renderLogin(w http.ResponseWriter, errMsg string) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
_ = s.cookies.Execute(w, map[string]string{"Error": errMsg})
}
const loginPageHTML = `<!doctype html>
<html lang="en"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Web VNC</title><style>
*{box-sizing:border-box}
body{font-family:system-ui,Segoe UI,sans-serif;background:#0f1720;color:#e2e8f0;display:flex;align-items:center;justify-content:center;height:100vh;margin:0}
.card{background:#111827;padding:2rem 2.25rem;border-radius:14px;box-shadow:0 10px 40px rgba(0,0,0,.5);width:320px}
h1{font-size:1.3rem;margin:0 0 .25rem;text-align:center}
.sub{color:#94a3b8;font-size:.8rem;text-align:center;margin:0 0 1.4rem}
label{display:block;font-size:.8rem;margin-bottom:.35rem;color:#cbd5e1}
input{width:100%;padding:.6rem .7rem;border-radius:8px;border:1px solid #334155;background:#0b1220;color:#e2e8f0;font-size:.95rem}
button{width:100%;margin-top:1.1rem;padding:.65rem;border:none;border-radius:8px;background:#2563eb;color:#fff;font-weight:600;font-size:.95rem;cursor:pointer}
button:hover{background:#1d4ed8}
.err{color:#f87171;font-size:.8rem;margin:.7rem 0 0;text-align:center;min-height:1em}
</style></head><body><form class="card" method="post" action="/login" autocomplete="off">
<h1>🖥️ Web VNC</h1><p class="sub">Enter the access password</p>
<label for="password">Password</label>
<input id="password" name="password" type="password" autofocus required>
<button type="submit">Connect</button>
<div class="err">{{.Error}}</div>
</form></body></html>`