diff --git a/cmd/tailscale/cli/web.go b/cmd/tailscale/cli/web.go index a3046efdb..94e4ca343 100644 --- a/cmd/tailscale/cli/web.go +++ b/cmd/tailscale/cli/web.go @@ -17,10 +17,12 @@ import ( "net/http/cgi" "os/exec" "runtime" + "strings" "github.com/peterbourgon/ff/v2/ffcli" "tailscale.com/client/tailscale" "tailscale.com/ipn" + "tailscale.com/tailcfg" "tailscale.com/types/preftype" "tailscale.com/version/distro" ) @@ -31,6 +33,7 @@ var webHTML string var tmpl = template.Must(template.New("html").Parse(webHTML)) type tmplData struct { + Profile tailcfg.UserProfile SynologyUser string Status string DeviceName string @@ -117,6 +120,67 @@ req.send(null); ` +const authenticationRedirectHTML = ` + + + Redirecting... + + + +
+
Redirecting...
+ +` + func webHandler(w http.ResponseWriter, r *http.Request) { if synoTokenRedirect(w, r) { return @@ -128,6 +192,11 @@ func webHandler(w http.ResponseWriter, r *http.Request) { return } + if r.URL.Path == "/redirect" || r.URL.Path == "/redirect/" { + w.Write([]byte(authenticationRedirectHTML)) + return + } + if r.Method == "POST" { type mi map[string]interface{} w.Header().Set("Content-Type", "application/json") @@ -143,12 +212,16 @@ func webHandler(w http.ResponseWriter, r *http.Request) { st, err := tailscale.Status(r.Context()) if err != nil { http.Error(w, err.Error(), 500) + return } + profile := st.User[st.Self.UserID] + deviceName := strings.Split(st.Self.DNSName, ".")[0] data := tmplData{ SynologyUser: user, + Profile: profile, Status: st.BackendState, - DeviceName: st.Self.DNSName, + DeviceName: deviceName, } if len(st.TailscaleIPs) != 0 { data.IP = st.TailscaleIPs[0].String() diff --git a/cmd/tailscale/cli/web.html b/cmd/tailscale/cli/web.html index 99f54561f..59c254643 100644 --- a/cmd/tailscale/cli/web.html +++ b/cmd/tailscale/cli/web.html @@ -1,47 +1,1488 @@ -Tailscale Client -

Tailscale

-
{{.SynologyUser}}
- - - - -
Status:{{.Status}}
Device Name:{{.DeviceName}}
Tailscale IP:{{.IP}}
- -

- - + + + + + + Tailscale + + + + +
+
+ + + + + + + + + + + +
+ {{ with .Profile.LoginName }} +
+

{{.}}

+ Switch account +
+ {{ end }} +
+ {{ with .Profile.ProfilePicURL }} +
+ {{ else }} +
+ {{ end }} +
+
+
+ {{ if .IP }} +
+
+ + + + + + +

{{.DeviceName}}

+
+
{{.IP}}
+
+ {{ end }} + {{ if or (eq .Status "NeedsLogin") (eq .Status "NoState") }} + {{ if .IP }} +
+

Your device's key has expired. Reauthenticate this device by logging in again, or learn more.

+
+ + + + {{ else }} +
+

Log in

+

Get started by logging in to your Tailscale network. Or, learn more at tailscale.com.

+
+ + + + {{ end }} + {{ else if eq .Status "NeedsMachineAuth" }} +
+ This device is authorized, but needs approval from a network admin before it can connect to the network. +
+ {{ else }} +
+

You are connected! Access this device over Tailscale using the device name or IP address above.

+
+ Reauthenticate + {{ end }} +
+ +