From fe69cc3399b2b2dce99d5c7e5d23ea98fae2e7ff Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 02:56:30 +0800 Subject: [PATCH 01/36] fix: prepend all templates with backlink value --- web/templates/configure.html | 2 +- web/templates/forgot.html | 2 +- web/templates/header.html | 22 +++++++++++----------- web/templates/index.html | 18 +++++++++--------- web/templates/profile/connect.html | 20 ++++++++++---------- web/templates/profile/delete.html | 4 ++-- web/templates/settings.html | 14 +++++++------- web/templates/signin.html | 6 +++--- web/templates/user/delete.html | 4 ++-- web/templates/user/edit.html | 10 +++++----- 10 files changed, 51 insertions(+), 51 deletions(-) diff --git a/web/templates/configure.html b/web/templates/configure.html index 7ea4ed4c..c83a360f 100644 --- a/web/templates/configure.html +++ b/web/templates/configure.html @@ -34,7 +34,7 @@ -
+
Email Address
diff --git a/web/templates/forgot.html b/web/templates/forgot.html index 9582e88c..f30878ea 100644 --- a/web/templates/forgot.html +++ b/web/templates/forgot.html @@ -40,7 +40,7 @@ {{$email := $.Request.FormValue "email"}} {{$secret := $.Request.FormValue "secret"}} - + {{if and $email $secret}} diff --git a/web/templates/header.html b/web/templates/header.html index 081d0274..f0b5a633 100644 --- a/web/templates/header.html +++ b/web/templates/header.html @@ -5,17 +5,17 @@ - - + + Subspace - - - + + + - - + + @@ -24,9 +24,9 @@ {{if $.Backlink}} {{end}} - Subspace + Subspace {{if $.Admin}} - Settings + Settings {{end}} {{if eq $.Section "signin" "forgot"}} @@ -40,8 +40,8 @@ {{end}}
{{end}} diff --git a/web/templates/index.html b/web/templates/index.html index 8f138b93..5e65ce1a 100644 --- a/web/templates/index.html +++ b/web/templates/index.html @@ -13,7 +13,7 @@ User deleted successfully {{end}} - + {{end}} {{with $error := $.Request.FormValue "error"}} @@ -30,7 +30,7 @@ {{$error}} {{end}} - + @@ -47,7 +47,7 @@
- +
@@ -104,7 +104,7 @@
{{range $n, $p := $.TargetProfiles}}
- + {{end}} @@ -164,7 +164,7 @@
{{range $n, $p := $.Profiles}}
- + {{end}} @@ -222,7 +222,7 @@
{{range $n, $u := $.Users}}
- +
@@ -256,7 +256,7 @@
{{end}} diff --git a/web/templates/profile/connect.html b/web/templates/profile/connect.html index b7cd4a2f..49173cbe 100644 --- a/web/templates/profile/connect.html +++ b/web/templates/profile/connect.html @@ -1,7 +1,7 @@ {{template "header.html" .}}
- Back + Back {{with $success := $.Request.FormValue "success"}} @@ -14,7 +14,7 @@ {{$success}} {{end}}
- +
@@ -39,7 +39,7 @@
- Download your WireGuard config and import it into WireGuard + Download your WireGuard config and import it into WireGuard
@@ -59,7 +59,7 @@
- Download your WireGuard config into your Downloads folder + Download your WireGuard config into your Downloads folder
@@ -119,7 +119,7 @@
- Download your WireGuard config and open with WireGuard or use the QR code below + Download your WireGuard config and open with WireGuard or use the QR code below
@@ -142,7 +142,7 @@
- qr-code could not be displayed + qr-code could not be displayed {{else if eq $.Profile.Platform "android"}}
Android — Instructions
@@ -159,7 +159,7 @@
- Download your WireGuard config or use the QR code below + Download your WireGuard config or use the QR code below
@@ -174,7 +174,7 @@ - qr-code could not be displayed + qr-code could not be displayed {{else if eq $.Profile.Platform "linux"}}
Linux — Instructions
@@ -191,7 +191,7 @@ @@ -219,7 +219,7 @@ diff --git a/web/templates/profile/delete.html b/web/templates/profile/delete.html index 15ca10a1..9a775073 100644 --- a/web/templates/profile/delete.html +++ b/web/templates/profile/delete.html @@ -12,10 +12,10 @@ - +
- Cancel + Cancel
diff --git a/web/templates/settings.html b/web/templates/settings.html index be750201..e2ef30be 100644 --- a/web/templates/settings.html +++ b/web/templates/settings.html @@ -17,7 +17,7 @@ TOTP reset for default user, please reconfigure for improved security. {{end}} - + {{end}} @@ -39,7 +39,7 @@ {{end}} -
+
Single Sign-On (SAML)
@@ -70,7 +70,7 @@
- Cancel + Cancel
@@ -97,7 +97,7 @@
- Cancel + Cancel
@@ -113,7 +113,7 @@
- Cancel + Cancel
@@ -125,7 +125,7 @@
Secret: {{$.TempTotpKey.Secret}}
- TOTP qr-code could not be displayed + TOTP qr-code could not be displayed
@@ -137,7 +137,7 @@
- Cancel + Cancel
diff --git a/web/templates/signin.html b/web/templates/signin.html index f06bfc4f..43d516d5 100644 --- a/web/templates/signin.html +++ b/web/templates/signin.html @@ -25,7 +25,7 @@ {{$ssoprovider := ssoprovider}} - {{if eq $ssoprovider "Google"}}{{end}}Sign in with {{$ssoprovider}} + {{if eq $ssoprovider "Google"}}{{end}}Sign in with {{$ssoprovider}} @@ -33,7 +33,7 @@
Admin Sign In
- +
@@ -59,7 +59,7 @@ diff --git a/web/templates/user/delete.html b/web/templates/user/delete.html index b96babae..e5633771 100644 --- a/web/templates/user/delete.html +++ b/web/templates/user/delete.html @@ -12,10 +12,10 @@
-
+
- Cancel + Cancel
diff --git a/web/templates/user/edit.html b/web/templates/user/edit.html index 031b82ee..3628385c 100644 --- a/web/templates/user/edit.html +++ b/web/templates/user/edit.html @@ -1,7 +1,7 @@ {{template "header.html" .}}
- Back + Back
@@ -14,7 +14,7 @@
{{range $n, $p := $.Profiles}}
- + {{end}} @@ -66,7 +66,7 @@
-
+
@@ -77,7 +77,7 @@ {{end}}
From c0a00adc517b05f02c0d20829dfde902e9c3de0c Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 04:17:30 +0800 Subject: [PATCH 02/36] fix: prepend all golang files with backlink variable --- cmd/subspace/handlers.go | 94 ++++++++++++++++++++-------------------- cmd/subspace/main.go | 74 +++++++++++++++---------------- cmd/subspace/web.go | 10 ++--- 3 files changed, 89 insertions(+), 89 deletions(-) diff --git a/cmd/subspace/handlers.go b/cmd/subspace/handlers.go index 229417be..354d600c 100644 --- a/cmd/subspace/handlers.go +++ b/cmd/subspace/handlers.go @@ -18,13 +18,6 @@ import ( qrcode "github.com/skip2/go-qrcode" ) -var ( - validEmail = regexp.MustCompile(`^[ -~]+@[ -~]+$`) - validPassword = regexp.MustCompile(`^[ -~]{6,200}$`) - validString = regexp.MustCompile(`^[ -~]{1,200}$`) - maxProfiles = 250 -) - func getEnv(key, fallback string) string { if value, ok := os.LookupEnv(key); ok { return value @@ -32,11 +25,18 @@ func getEnv(key, fallback string) string { return fallback } +var ( + validEmail = regexp.MustCompile(`^[ -~]+@[ -~]+$`) + validPassword = regexp.MustCompile(`^[ -~]{6,200}$`) + validString = regexp.MustCompile(`^[ -~]{1,200}$`) + maxProfiles = 250 +) + // Handles the sign in part separately from the SAML func ssoHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { session, err := samlSP.Session.GetSession(r) if session != nil { - http.Redirect(w, r, "/", http.StatusFound) + http.Redirect(w, r, backlink + "/", http.StatusFound) return } if err == samlsp.ErrNoSession { @@ -120,7 +120,7 @@ func wireguardConfigHandler(w *Web) { func configureHandler(w *Web) { if config.FindInfo().Configured { - w.Redirect("/?error=configured") + w.Redirect(backlink + "/?error=configured") return } @@ -134,13 +134,13 @@ func configureHandler(w *Web) { password := w.r.FormValue("password") if !validEmail.MatchString(email) || !validPassword.MatchString(password) || email != emailConfirm { - w.Redirect("/configure?error=invalid") + w.Redirect(backlink + "/configure?error=invalid") return } hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { - w.Redirect("/forgot?error=bcrypt") + w.Redirect(backlink + "/forgot?error=bcrypt") return } config.UpdateInfo(func(i *Info) error { @@ -154,7 +154,7 @@ func configureHandler(w *Web) { Error(w.w, err) return } - w.Redirect("/settings?success=configured") + w.Redirect(backlink + "/settings?success=configured") } func forgotHandler(w *Web) { @@ -168,20 +168,20 @@ func forgotHandler(w *Web) { password := w.r.FormValue("password") if email != "" && !validEmail.MatchString(email) { - w.Redirect("/forgot?error=invalid") + w.Redirect(backlink + "/forgot?error=invalid") return } if secret != "" && !validString.MatchString(secret) { - w.Redirect("/forgot?error=invalid") + w.Redirect(backlink + "/forgot?error=invalid") return } if email != "" && secret != "" && !validPassword.MatchString(password) { - w.Redirect("/forgot?error=invalid&email=%s&secret=%s", email, secret) + w.Redirect(backlink + "/forgot?error=invalid&email=%s&secret=%s", email, secret) return } if email != config.FindInfo().Email { - w.Redirect("/forgot?error=invalid") + w.Redirect(backlink + "/forgot?error=invalid") return } @@ -203,18 +203,18 @@ func forgotHandler(w *Web) { } }() - w.Redirect("/forgot?success=forgot") + w.Redirect(backlink + "/forgot?success=forgot") return } if secret != config.FindInfo().Secret { - w.Redirect("/forgot?error=invalid") + w.Redirect(backlink + "/forgot?error=invalid") return } hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { - w.Redirect("/forgot?error=bcrypt") + w.Redirect(backlink + "/forgot?error=bcrypt") return } config.UpdateInfo(func(i *Info) error { @@ -227,12 +227,12 @@ func forgotHandler(w *Web) { Error(w.w, err) return } - w.Redirect("/") + w.Redirect(backlink + "/") } func signoutHandler(w *Web) { w.SignoutSession() - w.Redirect("/signin") + w.Redirect(backlink + "/signin") } func signinHandler(w *Web) { @@ -246,18 +246,18 @@ func signinHandler(w *Web) { passcode := w.r.FormValue("totp") if email != config.FindInfo().Email { - w.Redirect("/signin?error=invalid") + w.Redirect(backlink + "/signin?error=invalid") return } if err := bcrypt.CompareHashAndPassword(config.FindInfo().Password, []byte(password)); err != nil { - w.Redirect("/signin?error=invalid") + w.Redirect(backlink + "/signin?error=invalid") return } if config.FindInfo().TotpKey != "" && !totp.Validate(passcode, config.FindInfo().TotpKey) { // Totp has been configured and the provided code doesn't match - w.Redirect("/signin?error=invalid") + w.Redirect(backlink + "/signin?error=invalid") return } @@ -266,7 +266,7 @@ func signinHandler(w *Web) { return } - w.Redirect("/") + w.Redirect(backlink + "/") } func totpQRHandler(w *Web) { @@ -277,7 +277,7 @@ func totpQRHandler(w *Web) { if config.Info.TotpKey != "" { // TOTP is already configured, don't allow the current one to be leaked - w.Redirect("/") + w.Redirect(backlink + "/") return } @@ -322,7 +322,7 @@ func userEditHandler(w *Web) { } if w.User.ID == user.ID { - w.Redirect("/user/edit/%s", user.ID) + w.Redirect(backlink + "/user/edit/%s", user.ID) return } @@ -333,7 +333,7 @@ func userEditHandler(w *Web) { return nil }) - w.Redirect("/user/edit/%s?success=edituser", user.ID) + w.Redirect(backlink + "/user/edit/%s?success=edituser", user.ID) } func userDeleteHandler(w *Web) { @@ -351,7 +351,7 @@ func userDeleteHandler(w *Web) { return } if w.User.ID == user.ID { - w.Redirect("/user/edit/%s?error=deleteuser", user.ID) + w.Redirect(backlink + "/user/edit/%s?error=deleteuser", user.ID) return } @@ -364,7 +364,7 @@ func userDeleteHandler(w *Web) { for _, profile := range config.ListProfilesByUser(user.ID) { if err := deleteProfile(profile); err != nil { logger.Errorf("delete profile failed: %s", err) - w.Redirect("/profile/delete?error=deleteprofile") + w.Redirect(backlink + "/profile/delete?error=deleteprofile") return } } @@ -373,7 +373,7 @@ func userDeleteHandler(w *Web) { Error(w.w, err) return } - w.Redirect("/?success=deleteuser") + w.Redirect(backlink + "/?success=deleteuser") } func profileAddHandler(w *Web) { @@ -391,7 +391,7 @@ func profileAddHandler(w *Web) { } if name == "" { - w.Redirect("/?error=profilename") + w.Redirect(backlink + "/?error=profilename") return } @@ -403,14 +403,14 @@ func profileAddHandler(w *Web) { } if len(config.ListProfiles()) >= maxProfiles { - w.Redirect("/?error=addprofile") + w.Redirect(backlink + "/?error=addprofile") return } profile, err := config.AddProfile(userID, name, platform) if err != nil { logger.Warn(err) - w.Redirect("/?error=addprofile") + w.Redirect(backlink + "/?error=addprofile") return } @@ -527,11 +527,11 @@ WGCLIENT f, _ := os.Create("/tmp/error.txt") errstr := fmt.Sprintln(err) f.WriteString(errstr) - w.Redirect("/?error=addprofile") + w.Redirect(backlink + "/?error=addprofile") return } - w.Redirect("/profile/connect/%s?success=addprofile", profile.ID) + w.Redirect(backlink + "/profile/connect/%s?success=addprofile", profile.ID) } func profileConnectHandler(w *Web) { @@ -570,14 +570,14 @@ func profileDeleteHandler(w *Web) { } if err := deleteProfile(profile); err != nil { logger.Errorf("delete profile failed: %s", err) - w.Redirect("/profile/delete?error=deleteprofile") + w.Redirect(backlink + "/profile/delete?error=deleteprofile") return } if w.Admin { - w.Redirect("/user/edit/%s?success=deleteprofile", profile.UserID) + w.Redirect(backlink + "/user/edit/%s?success=deleteprofile", profile.UserID) return } - w.Redirect("/?success=deleteprofile") + w.Redirect(backlink + "/?success=deleteprofile") } func indexHandler(w *Web) { @@ -623,7 +623,7 @@ func settingsHandler(w *Web) { if len(samlMetadata) > 0 { if err := configureSAML(); err != nil { logger.Warnf("configuring SAML failed: %s", err) - w.Redirect("/settings?error=saml") + w.Redirect(backlink + "/settings?error=saml") } } else { samlSP = nil @@ -631,18 +631,18 @@ func settingsHandler(w *Web) { if currentPassword != "" || newPassword != "" { if !validPassword.MatchString(newPassword) { - w.Redirect("/settings?error=invalid") + w.Redirect(backlink + "/settings?error=invalid") return } if err := bcrypt.CompareHashAndPassword(config.FindInfo().Password, []byte(currentPassword)); err != nil { - w.Redirect("/settings?error=invalid") + w.Redirect(backlink + "/settings?error=invalid") return } hashedPassword, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost) if err != nil { - w.Redirect("/settings?error=bcrypt") + w.Redirect(backlink + "/settings?error=bcrypt") return } @@ -655,24 +655,24 @@ func settingsHandler(w *Web) { if resetTotp == "true" { err := config.ResetTotp() if err != nil { - w.Redirect("/settings?error=totp") + w.Redirect(backlink + "/settings?error=totp") return } - w.Redirect("/settings?success=totp") + w.Redirect(backlink + "/settings?success=totp") return } if config.Info.TotpKey == "" && totpCode != "" { if !totp.Validate(totpCode, tempTotpKey.Secret()) { - w.Redirect("/settings?error=totp") + w.Redirect(backlink + "/settings?error=totp") return } config.Info.TotpKey = tempTotpKey.Secret() config.save() } - w.Redirect("/settings?success=settings") + w.Redirect(backlink + "/settings?success=settings") } func helpHandler(w *Web) { diff --git a/cmd/subspace/main.go b/cmd/subspace/main.go index 1956ac9d..c6ecf658 100644 --- a/cmd/subspace/main.go +++ b/cmd/subspace/main.go @@ -87,7 +87,7 @@ var ( func init() { cli.StringVar(&datadir, "datadir", "/data", "data dir") - cli.StringVar(&backlink, "backlink", "/", "backlink (optional)") + cli.StringVar(&backlink, "backlink", "", "backlink, without trailing slash (optional)") cli.StringVar(&httpHost, "http-host", "", "HTTP host") cli.StringVar(&httpAddr, "http-addr", ":80", "HTTP listen address") cli.BoolVar(&httpInsecure, "http-insecure", false, "enable sessions cookies for http (no https) not recommended") @@ -168,41 +168,41 @@ func main() { // Routes // r := &httprouter.Router{} - r.GET("/", Log(WebHandler(indexHandler, "index"))) - r.GET("/help", Log(WebHandler(helpHandler, "help"))) - r.GET("/configure", Log(WebHandler(configureHandler, "configure"))) - r.POST("/configure", Log(WebHandler(configureHandler, "configure"))) + r.GET(backlink + "/", Log(WebHandler(indexHandler, "index"))) + r.GET(backlink + "/help", Log(WebHandler(helpHandler, "help"))) + r.GET(backlink + "/configure", Log(WebHandler(configureHandler, "configure"))) + r.POST(backlink + "/configure", Log(WebHandler(configureHandler, "configure"))) // SAML - r.GET("/sso", Log(ssoHandler)) - r.GET("/saml/metadata", Log(samlHandler)) - r.POST("/saml/metadata", Log(samlHandler)) - r.GET("/saml/acs", Log(samlHandler)) - r.POST("/saml/acs", Log(samlHandler)) - - r.GET("/totp/image", Log(WebHandler(totpQRHandler, "totp/image"))) - r.GET("/signin", Log(WebHandler(signinHandler, "signin"))) - r.GET("/signout", Log(WebHandler(signoutHandler, "signout"))) - r.POST("/signin", Log(WebHandler(signinHandler, "signin"))) - r.GET("/forgot", Log(WebHandler(forgotHandler, "forgot"))) - r.POST("/forgot", Log(WebHandler(forgotHandler, "forgot"))) - - r.GET("/settings", Log(WebHandler(settingsHandler, "settings"))) - r.POST("/settings", Log(WebHandler(settingsHandler, "settings"))) - - r.GET("/user/edit/:user", Log(WebHandler(userEditHandler, "user/edit"))) - r.POST("/user/edit", Log(WebHandler(userEditHandler, "user/edit"))) - r.GET("/user/delete/:user", Log(WebHandler(userDeleteHandler, "user/delete"))) - r.POST("/user/delete", Log(WebHandler(userDeleteHandler, "user/delete"))) - - r.GET("/profile/add", Log(WebHandler(profileAddHandler, "profile/add"))) - r.POST("/profile/add", Log(WebHandler(profileAddHandler, "profile/add"))) - r.GET("/profile/connect/:profile", Log(WebHandler(profileConnectHandler, "profile/connect"))) - r.GET("/profile/delete/:profile", Log(WebHandler(profileDeleteHandler, "profile/delete"))) - r.POST("/profile/delete", Log(WebHandler(profileDeleteHandler, "profile/delete"))) - r.GET("/profile/config/wireguard/:profile", Log(WebHandler(wireguardConfigHandler, "profile/config/wireguard"))) - r.GET("/profile/qrconfig/wireguard/:profile", Log(WebHandler(wireguardQRConfigHandler, "profile/qrconfig/wireguard"))) - r.GET("/static/*path", staticHandler) + r.GET(backlink + "/sso", Log(ssoHandler)) + r.GET(backlink + "/saml/metadata", Log(samlHandler)) + r.POST(backlink + "/saml/metadata", Log(samlHandler)) + r.GET(backlink + "/saml/acs", Log(samlHandler)) + r.POST(backlink + "/saml/acs", Log(samlHandler)) + + r.GET(backlink + "/totp/image", Log(WebHandler(totpQRHandler, "totp/image"))) + r.GET(backlink + "/signin", Log(WebHandler(signinHandler, "signin"))) + r.GET(backlink + "/signout", Log(WebHandler(signoutHandler, "signout"))) + r.POST(backlink + "/signin", Log(WebHandler(signinHandler, "signin"))) + r.GET(backlink + "/forgot", Log(WebHandler(forgotHandler, "forgot"))) + r.POST(backlink + "/forgot", Log(WebHandler(forgotHandler, "forgot"))) + + r.GET(backlink + "/settings", Log(WebHandler(settingsHandler, "settings"))) + r.POST(backlink + "/settings", Log(WebHandler(settingsHandler, "settings"))) + + r.GET(backlink + "/user/edit/:user", Log(WebHandler(userEditHandler, "user/edit"))) + r.POST(backlink + "/user/edit", Log(WebHandler(userEditHandler, "user/edit"))) + r.GET(backlink + "/user/delete/:user", Log(WebHandler(userDeleteHandler, "user/delete"))) + r.POST(backlink + "/user/delete", Log(WebHandler(userDeleteHandler, "user/delete"))) + + r.GET(backlink + "/profile/add", Log(WebHandler(profileAddHandler, "profile/add"))) + r.POST(backlink + "/profile/add", Log(WebHandler(profileAddHandler, "profile/add"))) + r.GET(backlink + "/profile/connect/:profile", Log(WebHandler(profileConnectHandler, "profile/connect"))) + r.GET(backlink + "/profile/delete/:profile", Log(WebHandler(profileDeleteHandler, "profile/delete"))) + r.POST(backlink + "/profile/delete", Log(WebHandler(profileDeleteHandler, "profile/delete"))) + r.GET(backlink + "/profile/config/wireguard/:profile", Log(WebHandler(wireguardConfigHandler, "profile/config/wireguard"))) + r.GET(backlink + "/profile/qrconfig/wireguard/:profile", Log(WebHandler(wireguardQRConfigHandler, "profile/qrconfig/wireguard"))) + r.GET(backlink + "/static/*path", staticHandler) // // Server @@ -253,7 +253,7 @@ func main() { // http redirect to https and Let's Encrypt auth go func() { redir := httprouter.New() - redir.GET("/*path", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { + redir.GET(backlink + "/*path", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { r.URL.Scheme = "https" r.URL.Host = httpHost http.Redirect(w, r, r.URL.String(), http.StatusFound) @@ -318,7 +318,7 @@ func main() { logger.Infof("Subspace version: %s %s", version, &url.URL{ Scheme: "https", Host: hostport, - Path: "/", + Path: backlink + "/", }) logger.Fatal(httpsd.Serve(tlsListener)) } @@ -377,7 +377,7 @@ func configureSAML() error { rootURL := url.URL{ Scheme: "https", Host: httpHost, - Path: "/", + Path: backlink + "/", } if httpInsecure { diff --git a/cmd/subspace/web.go b/cmd/subspace/web.go index 81c55686..09c3055e 100644 --- a/cmd/subspace/web.go +++ b/cmd/subspace/web.go @@ -170,7 +170,7 @@ func WebHandler(h func(*Web), section string) httprouter.Handle { } if !config.FindInfo().Configured { - web.Redirect("/configure") + web.Redirect(backlink + "/configure") return } @@ -243,7 +243,7 @@ func WebHandler(h func(*Web), section string) httprouter.Handle { } logger.Warnf("auth: sign in required") - web.Redirect("/signin") + web.Redirect(backlink + "/signin") } } @@ -304,7 +304,7 @@ func (w *Web) SignoutSession() { http.SetCookie(w.w, &http.Cookie{ Name: SessionCookieNameSSO, Value: "", - Path: "/", + Path: backlink + "/", HttpOnly: true, Domain: httpHost, Secure: !httpInsecure, @@ -315,7 +315,7 @@ func (w *Web) SignoutSession() { http.SetCookie(w.w, &http.Cookie{ Name: SessionCookieName, Value: "", - Path: "/", + Path: backlink + "/", HttpOnly: true, Domain: httpHost, Secure: !httpInsecure, @@ -339,7 +339,7 @@ func (w *Web) SigninSession(admin bool, userID string) error { http.SetCookie(w.w, &http.Cookie{ Name: SessionCookieName, Value: encoded, - Path: "/", + Path: backlink + "/", HttpOnly: true, Domain: httpHost, Secure: !httpInsecure, From f33deffa9de034cc6c133c386ec3aca00bb72b1c Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 04:19:41 +0800 Subject: [PATCH 03/36] fix: remove trailing slash from entrypoint.sh --- entrypoint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/entrypoint.sh b/entrypoint.sh index 9b1814b2..3c1de44f 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -11,7 +11,7 @@ if [ -z "${SUBSPACE_HTTP_HOST-}" ]; then fi # Optional environment variables. if [ -z "${SUBSPACE_BACKLINK-}" ]; then - export SUBSPACE_BACKLINK="/" + export SUBSPACE_BACKLINK="" fi if [ -z "${SUBSPACE_IPV4_POOL-}" ]; then From 2f457bbeaf6f04c0b64cd3df8956a466922b16b0 Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 04:33:01 +0800 Subject: [PATCH 04/36] fix: display listening address correctly --- cmd/subspace/main.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cmd/subspace/main.go b/cmd/subspace/main.go index c6ecf658..3c962b94 100644 --- a/cmd/subspace/main.go +++ b/cmd/subspace/main.go @@ -224,10 +224,13 @@ func main() { if httpPort == "80" { hostport = httpHost } + if len(httpIP) == 0 { + hostport = "[::]:" + httpPort + } logger.Infof("Subspace version: %s %s", version, &url.URL{ Scheme: "http", Host: hostport, - Path: httpPrefix, + Path: backlink, }) logger.Fatal(httpd.ListenAndServe()) } @@ -315,6 +318,9 @@ func main() { if httpPort == "443" { hostport = httpHost } + if len(httpIP) == 0 { + hostport = "[::]:" + httpPort + } logger.Infof("Subspace version: %s %s", version, &url.URL{ Scheme: "https", Host: hostport, From 0867e853f4955d4d7724e06f165ca42e3eed9d16 Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 04:35:34 +0800 Subject: [PATCH 05/36] fix: remove trailing slash for cookies --- cmd/subspace/web.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/subspace/web.go b/cmd/subspace/web.go index 09c3055e..6fa919d8 100644 --- a/cmd/subspace/web.go +++ b/cmd/subspace/web.go @@ -304,7 +304,7 @@ func (w *Web) SignoutSession() { http.SetCookie(w.w, &http.Cookie{ Name: SessionCookieNameSSO, Value: "", - Path: backlink + "/", + Path: backlink, HttpOnly: true, Domain: httpHost, Secure: !httpInsecure, @@ -315,7 +315,7 @@ func (w *Web) SignoutSession() { http.SetCookie(w.w, &http.Cookie{ Name: SessionCookieName, Value: "", - Path: backlink + "/", + Path: backlink, HttpOnly: true, Domain: httpHost, Secure: !httpInsecure, @@ -339,7 +339,7 @@ func (w *Web) SigninSession(admin bool, userID string) error { http.SetCookie(w.w, &http.Cookie{ Name: SessionCookieName, Value: encoded, - Path: backlink + "/", + Path: backlink, HttpOnly: true, Domain: httpHost, Secure: !httpInsecure, From 3e7098d2fb741ca49f65ff3184ab4a93e78fffb4 Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 04:36:19 +0800 Subject: [PATCH 06/36] fix: remove trailing slash for version info message --- cmd/subspace/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/subspace/main.go b/cmd/subspace/main.go index 3c962b94..ad7e9189 100644 --- a/cmd/subspace/main.go +++ b/cmd/subspace/main.go @@ -324,7 +324,7 @@ func main() { logger.Infof("Subspace version: %s %s", version, &url.URL{ Scheme: "https", Host: hostport, - Path: backlink + "/", + Path: backlink, }) logger.Fatal(httpsd.Serve(tlsListener)) } From 73da0fe4dc63e6944da88285527049003db4be35 Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 04:51:21 +0800 Subject: [PATCH 07/36] patch: escalate all Backlink template variable to top level access --- web/templates/configure.html | 2 +- web/templates/forgot.html | 2 +- web/templates/header.html | 24 ++++++++++++------------ web/templates/index.html | 18 +++++++++--------- web/templates/profile/connect.html | 20 ++++++++++---------- web/templates/profile/delete.html | 4 ++-- web/templates/settings.html | 14 +++++++------- web/templates/signin.html | 6 +++--- web/templates/user/delete.html | 4 ++-- web/templates/user/edit.html | 10 +++++----- 10 files changed, 52 insertions(+), 52 deletions(-) diff --git a/web/templates/configure.html b/web/templates/configure.html index c83a360f..d1409f52 100644 --- a/web/templates/configure.html +++ b/web/templates/configure.html @@ -34,7 +34,7 @@ -
+
Email Address
diff --git a/web/templates/forgot.html b/web/templates/forgot.html index f30878ea..58bc9b3a 100644 --- a/web/templates/forgot.html +++ b/web/templates/forgot.html @@ -40,7 +40,7 @@ {{$email := $.Request.FormValue "email"}} {{$secret := $.Request.FormValue "secret"}} - + {{if and $email $secret}} diff --git a/web/templates/header.html b/web/templates/header.html index f0b5a633..abb5c0f2 100644 --- a/web/templates/header.html +++ b/web/templates/header.html @@ -5,28 +5,28 @@ - - + + Subspace - - - + + + - - + + - +
{{end}} {{with $error := $.Request.FormValue "error"}} @@ -30,7 +30,7 @@ {{$error}} {{end}}
- +
@@ -47,7 +47,7 @@
- +
@@ -104,7 +104,7 @@
{{range $n, $p := $.TargetProfiles}}
- + {{end}} @@ -164,7 +164,7 @@
{{range $n, $p := $.Profiles}}
- + {{end}} @@ -222,7 +222,7 @@
{{range $n, $u := $.Users}}
- +
@@ -256,7 +256,7 @@
{{end}} diff --git a/web/templates/profile/connect.html b/web/templates/profile/connect.html index 49173cbe..a9176a78 100644 --- a/web/templates/profile/connect.html +++ b/web/templates/profile/connect.html @@ -1,7 +1,7 @@ {{template "header.html" .}}
- Back + Back {{with $success := $.Request.FormValue "success"}} @@ -14,7 +14,7 @@ {{$success}} {{end}}
- +
@@ -39,7 +39,7 @@
- Download your WireGuard config and import it into WireGuard + Download your WireGuard config and import it into WireGuard
@@ -59,7 +59,7 @@
- Download your WireGuard config into your Downloads folder + Download your WireGuard config into your Downloads folder
@@ -119,7 +119,7 @@
- Download your WireGuard config and open with WireGuard or use the QR code below + Download your WireGuard config and open with WireGuard or use the QR code below
@@ -142,7 +142,7 @@
- qr-code could not be displayed + qr-code could not be displayed {{else if eq $.Profile.Platform "android"}}
Android — Instructions
@@ -159,7 +159,7 @@
- Download your WireGuard config or use the QR code below + Download your WireGuard config or use the QR code below
@@ -174,7 +174,7 @@
- qr-code could not be displayed + qr-code could not be displayed {{else if eq $.Profile.Platform "linux"}}
Linux — Instructions
@@ -191,7 +191,7 @@
@@ -219,7 +219,7 @@
diff --git a/web/templates/profile/delete.html b/web/templates/profile/delete.html index 9a775073..7e3dd5c8 100644 --- a/web/templates/profile/delete.html +++ b/web/templates/profile/delete.html @@ -12,10 +12,10 @@
- +
- Cancel + Cancel
diff --git a/web/templates/settings.html b/web/templates/settings.html index e2ef30be..91ce2e36 100644 --- a/web/templates/settings.html +++ b/web/templates/settings.html @@ -17,7 +17,7 @@ TOTP reset for default user, please reconfigure for improved security. {{end}} - + {{end}} @@ -39,7 +39,7 @@ {{end}} -
+
Single Sign-On (SAML)
@@ -70,7 +70,7 @@
- Cancel + Cancel
@@ -97,7 +97,7 @@
- Cancel + Cancel
@@ -113,7 +113,7 @@
- Cancel + Cancel
@@ -125,7 +125,7 @@
Secret: {{$.TempTotpKey.Secret}}
- TOTP qr-code could not be displayed + TOTP qr-code could not be displayed
@@ -137,7 +137,7 @@
- Cancel + Cancel
diff --git a/web/templates/signin.html b/web/templates/signin.html index 43d516d5..8eed40d6 100644 --- a/web/templates/signin.html +++ b/web/templates/signin.html @@ -25,7 +25,7 @@ {{$ssoprovider := ssoprovider}} - {{if eq $ssoprovider "Google"}}{{end}}Sign in with {{$ssoprovider}} + {{if eq $ssoprovider "Google"}}{{end}}Sign in with {{$ssoprovider}} @@ -33,7 +33,7 @@
Admin Sign In
- +
@@ -59,7 +59,7 @@ diff --git a/web/templates/user/delete.html b/web/templates/user/delete.html index e5633771..d4d3ddaf 100644 --- a/web/templates/user/delete.html +++ b/web/templates/user/delete.html @@ -12,10 +12,10 @@
-
+
- Cancel + Cancel
diff --git a/web/templates/user/edit.html b/web/templates/user/edit.html index 3628385c..cf51663c 100644 --- a/web/templates/user/edit.html +++ b/web/templates/user/edit.html @@ -1,7 +1,7 @@ {{template "header.html" .}}
- Back + Back
@@ -14,7 +14,7 @@
{{range $n, $p := $.Profiles}}
- + {{end}} @@ -66,7 +66,7 @@
-
+
@@ -77,7 +77,7 @@ {{end}}
From e6f205ccf9640e7d683826478c7157e81fd614a8 Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 04:56:39 +0800 Subject: [PATCH 08/36] fix: HTML template message typo on 'deleteprofile' error --- web/templates/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/templates/index.html b/web/templates/index.html index ef930196..39f06b72 100644 --- a/web/templates/index.html +++ b/web/templates/index.html @@ -23,7 +23,7 @@ {{if eq $error "addprofile"}} Adding device failed {{else if eq $error "deleteprofile"}} - Adding device failed + Deleting device failed {{else if eq $error "profilename"}} Device name is required {{else}} From 0cb20f857e0683793c67b9d522230d8f9f9f664f Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 05:16:04 +0800 Subject: [PATCH 09/36] patch: fundamentally remove all trailing slash behaviour --- cmd/subspace/handlers.go | 10 +++++++--- cmd/subspace/main.go | 4 +++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/cmd/subspace/handlers.go b/cmd/subspace/handlers.go index 354d600c..094e15d1 100644 --- a/cmd/subspace/handlers.go +++ b/cmd/subspace/handlers.go @@ -36,7 +36,7 @@ var ( func ssoHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { session, err := samlSP.Session.GetSession(r) if session != nil { - http.Redirect(w, r, backlink + "/", http.StatusFound) + http.Redirect(w, r, backlink, http.StatusFound) return } if err == samlsp.ErrNoSession { @@ -227,7 +227,7 @@ func forgotHandler(w *Web) { Error(w.w, err) return } - w.Redirect(backlink + "/") + w.Redirect(backlink) } func signoutHandler(w *Web) { @@ -266,7 +266,7 @@ func signinHandler(w *Web) { return } - w.Redirect(backlink + "/") + w.Redirect(backlink) } func totpQRHandler(w *Web) { @@ -581,6 +581,10 @@ func profileDeleteHandler(w *Web) { } func indexHandler(w *Web) { + w.Redirect(backlink) +} + +func rootIndexHandler(w *Web) { if w.User.ID != "" { w.TargetProfiles = config.ListProfilesByUser(w.User.ID) } diff --git a/cmd/subspace/main.go b/cmd/subspace/main.go index ad7e9189..b10c7b2c 100644 --- a/cmd/subspace/main.go +++ b/cmd/subspace/main.go @@ -168,6 +168,8 @@ func main() { // Routes // r := &httprouter.Router{} + + r.GET(backlink, Log(WebHandler(rootIndexHandler, "index"))) r.GET(backlink + "/", Log(WebHandler(indexHandler, "index"))) r.GET(backlink + "/help", Log(WebHandler(helpHandler, "help"))) r.GET(backlink + "/configure", Log(WebHandler(configureHandler, "configure"))) @@ -383,7 +385,7 @@ func configureSAML() error { rootURL := url.URL{ Scheme: "https", Host: httpHost, - Path: backlink + "/", + Path: backlink, } if httpInsecure { From 94cdecdfc3c9f4583de314fff4ccfd5339fcc539 Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 05:18:27 +0800 Subject: [PATCH 10/36] patch: prepend backlink value to SAML URLs --- web/templates/settings.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/templates/settings.html b/web/templates/settings.html index 91ce2e36..b067a186 100644 --- a/web/templates/settings.html +++ b/web/templates/settings.html @@ -55,11 +55,11 @@
Your ACS URL
- +
Your Entity ID
- +
IDP Metadata
From a9cb880dc2df1fc2f740196d18031cd166dee9b3 Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 05:36:36 +0800 Subject: [PATCH 11/36] [important] fix: match LAN subnet to user config --- entrypoint.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/entrypoint.sh b/entrypoint.sh index 3c1de44f..57d89e05 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -46,14 +46,19 @@ fi export DEBIAN_FRONTEND="noninteractive" -if [ -z "${SUBSPACE_IPV4_GW-}" ]; then +if [ -z "${SUBSPACE_IPV4_PREF-}" ]; then export SUBSPACE_IPV4_PREF=$(echo ${SUBSPACE_IPV4_POOL-} | cut -d '/' -f1 | sed 's/.0$/./g') - export SUBSPACE_IPV4_GW=$(echo ${SUBSPACE_IPV4_PREF-}1) +fi +if [ -z "${SUBSPACE_IPV6_PREF-}" ]; then + export SUBSPACE_IPV6_PREF=$(echo ${SUBSPACE_IPV6_POOL-} | cut -d '/' -f1 | sed 's/:0$/:/g') +fi + +if [ -z "${SUBSPACE_IPV4_GW-}" ]; then + export SUBSPACE_IPV4_GW=$(echo ${SUBSPACE_IPV4_PREF-}1) fi if [ -z "${SUBSPACE_IPV6_GW-}" ]; then - export SUBSPACE_IPV6_PREF=$(echo ${SUBSPACE_IPV6_POOL-} | cut -d '/' -f1 | sed 's/:0$/:/g') export SUBSPACE_IPV6_GW=$(echo ${SUBSPACE_IPV6_PREF-}1) fi From 8e9e284ee633c5b0dca5201ed87749430b82677f Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 05:57:42 +0800 Subject: [PATCH 12/36] [important] fix: make sure user is a valid multiuser admin --- cmd/subspace/handlers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/subspace/handlers.go b/cmd/subspace/handlers.go index 094e15d1..d454410f 100644 --- a/cmd/subspace/handlers.go +++ b/cmd/subspace/handlers.go @@ -573,7 +573,7 @@ func profileDeleteHandler(w *Web) { w.Redirect(backlink + "/profile/delete?error=deleteprofile") return } - if w.Admin { + if len(profile.UserID) > 0 && w.Admin { w.Redirect(backlink + "/user/edit/%s?success=deleteprofile", profile.UserID) return } From 8fe00ef37b8841f2cdf3ac29cc64698a7f24489b Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 06:06:57 +0800 Subject: [PATCH 13/36] patch: remove more trailing slash behaviour --- cmd/subspace/handlers.go | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/cmd/subspace/handlers.go b/cmd/subspace/handlers.go index d454410f..481a4736 100644 --- a/cmd/subspace/handlers.go +++ b/cmd/subspace/handlers.go @@ -120,7 +120,7 @@ func wireguardConfigHandler(w *Web) { func configureHandler(w *Web) { if config.FindInfo().Configured { - w.Redirect(backlink + "/?error=configured") + w.Redirect(backlink + "?error=configured") return } @@ -176,7 +176,7 @@ func forgotHandler(w *Web) { return } if email != "" && secret != "" && !validPassword.MatchString(password) { - w.Redirect(backlink + "/forgot?error=invalid&email=%s&secret=%s", email, secret) + w.Redirect(backlink+"/forgot?error=invalid&email=%s&secret=%s", email, secret) return } @@ -322,7 +322,7 @@ func userEditHandler(w *Web) { } if w.User.ID == user.ID { - w.Redirect(backlink + "/user/edit/%s", user.ID) + w.Redirect(backlink+"/user/edit/%s", user.ID) return } @@ -333,7 +333,7 @@ func userEditHandler(w *Web) { return nil }) - w.Redirect(backlink + "/user/edit/%s?success=edituser", user.ID) + w.Redirect(backlink+"/user/edit/%s?success=edituser", user.ID) } func userDeleteHandler(w *Web) { @@ -351,7 +351,7 @@ func userDeleteHandler(w *Web) { return } if w.User.ID == user.ID { - w.Redirect(backlink + "/user/edit/%s?error=deleteuser", user.ID) + w.Redirect(backlink+"/user/edit/%s?error=deleteuser", user.ID) return } @@ -373,7 +373,7 @@ func userDeleteHandler(w *Web) { Error(w.w, err) return } - w.Redirect(backlink + "/?success=deleteuser") + w.Redirect(backlink + "?success=deleteuser") } func profileAddHandler(w *Web) { @@ -391,7 +391,7 @@ func profileAddHandler(w *Web) { } if name == "" { - w.Redirect(backlink + "/?error=profilename") + w.Redirect(backlink + "?error=profilename") return } @@ -403,14 +403,14 @@ func profileAddHandler(w *Web) { } if len(config.ListProfiles()) >= maxProfiles { - w.Redirect(backlink + "/?error=addprofile") + w.Redirect(backlink + "?error=addprofile") return } profile, err := config.AddProfile(userID, name, platform) if err != nil { logger.Warn(err) - w.Redirect(backlink + "/?error=addprofile") + w.Redirect(backlink + "?error=addprofile") return } @@ -527,11 +527,11 @@ WGCLIENT f, _ := os.Create("/tmp/error.txt") errstr := fmt.Sprintln(err) f.WriteString(errstr) - w.Redirect(backlink + "/?error=addprofile") + w.Redirect(backlink + "?error=addprofile") return } - w.Redirect(backlink + "/profile/connect/%s?success=addprofile", profile.ID) + w.Redirect(backlink+"/profile/connect/%s?success=addprofile", profile.ID) } func profileConnectHandler(w *Web) { @@ -574,10 +574,10 @@ func profileDeleteHandler(w *Web) { return } if len(profile.UserID) > 0 && w.Admin { - w.Redirect(backlink + "/user/edit/%s?success=deleteprofile", profile.UserID) + w.Redirect(backlink+"/user/edit/%s?success=deleteprofile", profile.UserID) return } - w.Redirect(backlink + "/?success=deleteprofile") + w.Redirect(backlink + "?success=deleteprofile") } func indexHandler(w *Web) { From a8e448d5e7bf6d1b504d45dcfd54f4ee4276c35b Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 06:28:02 +0800 Subject: [PATCH 14/36] patch: remove trailing slashes inside HTML templates --- web/templates/header.html | 2 +- web/templates/index.html | 4 ++-- web/templates/profile/connect.html | 2 +- web/templates/profile/delete.html | 2 +- web/templates/settings.html | 8 ++++---- web/templates/user/edit.html | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/web/templates/header.html b/web/templates/header.html index abb5c0f2..d68cb92a 100644 --- a/web/templates/header.html +++ b/web/templates/header.html @@ -24,7 +24,7 @@ {{if $.Backlink}} {{end}} - Subspace + Subspace {{if $.Admin}} Settings {{end}} diff --git a/web/templates/index.html b/web/templates/index.html index 39f06b72..8b614193 100644 --- a/web/templates/index.html +++ b/web/templates/index.html @@ -13,7 +13,7 @@ User deleted successfully {{end}}
- +
{{end}} {{with $error := $.Request.FormValue "error"}} @@ -30,7 +30,7 @@ {{$error}} {{end}}
- +
diff --git a/web/templates/profile/connect.html b/web/templates/profile/connect.html index a9176a78..efe3350b 100644 --- a/web/templates/profile/connect.html +++ b/web/templates/profile/connect.html @@ -1,7 +1,7 @@ {{template "header.html" .}}
- Back + Back {{with $success := $.Request.FormValue "success"}} diff --git a/web/templates/profile/delete.html b/web/templates/profile/delete.html index 7e3dd5c8..8c9daf4d 100644 --- a/web/templates/profile/delete.html +++ b/web/templates/profile/delete.html @@ -15,7 +15,7 @@
- Cancel + Cancel
diff --git a/web/templates/settings.html b/web/templates/settings.html index b067a186..20a44532 100644 --- a/web/templates/settings.html +++ b/web/templates/settings.html @@ -70,7 +70,7 @@
- Cancel + Cancel
@@ -97,7 +97,7 @@
- Cancel + Cancel
@@ -113,7 +113,7 @@
- Cancel + Cancel
@@ -137,7 +137,7 @@
- Cancel + Cancel
diff --git a/web/templates/user/edit.html b/web/templates/user/edit.html index cf51663c..655df623 100644 --- a/web/templates/user/edit.html +++ b/web/templates/user/edit.html @@ -1,7 +1,7 @@ {{template "header.html" .}}
- Back + Back
From d7af24c8d040d76215b3b1c72cd88c45ee6bb49b Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 06:52:38 +0800 Subject: [PATCH 15/36] [important] fix: enforce first time setup even URL points to auth endpoints --- cmd/subspace/web.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/subspace/web.go b/cmd/subspace/web.go index 6fa919d8..735a41db 100644 --- a/cmd/subspace/web.go +++ b/cmd/subspace/web.go @@ -164,13 +164,13 @@ func WebHandler(h func(*Web), section string) httprouter.Handle { TempTotpKey: tempTotpKey, } - if section == "signin" || section == "forgot" || section == "configure" { - h(web) + if !config.FindInfo().Configured { + web.Redirect(backlink + "/configure") return } - if !config.FindInfo().Configured { - web.Redirect(backlink + "/configure") + if section == "signin" || section == "forgot" || section == "configure" { + h(web) return } From 6cf175ec8353006f3879bd5ec27161ce34055bc7 Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 06:56:48 +0800 Subject: [PATCH 16/36] revert: code block positioning (variables in handlers.go) --- cmd/subspace/handlers.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cmd/subspace/handlers.go b/cmd/subspace/handlers.go index 481a4736..59d0387e 100644 --- a/cmd/subspace/handlers.go +++ b/cmd/subspace/handlers.go @@ -18,13 +18,6 @@ import ( qrcode "github.com/skip2/go-qrcode" ) -func getEnv(key, fallback string) string { - if value, ok := os.LookupEnv(key); ok { - return value - } - return fallback -} - var ( validEmail = regexp.MustCompile(`^[ -~]+@[ -~]+$`) validPassword = regexp.MustCompile(`^[ -~]{6,200}$`) @@ -32,6 +25,13 @@ var ( maxProfiles = 250 ) +func getEnv(key, fallback string) string { + if value, ok := os.LookupEnv(key); ok { + return value + } + return fallback +} + // Handles the sign in part separately from the SAML func ssoHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { session, err := samlSP.Session.GetSession(r) From 8ab3bd9621b6e4161cb539f926ee36293403808d Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 06:58:07 +0800 Subject: [PATCH 17/36] revert: spacing issue in handlers.go --- cmd/subspace/handlers.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd/subspace/handlers.go b/cmd/subspace/handlers.go index 59d0387e..e9335585 100644 --- a/cmd/subspace/handlers.go +++ b/cmd/subspace/handlers.go @@ -176,7 +176,7 @@ func forgotHandler(w *Web) { return } if email != "" && secret != "" && !validPassword.MatchString(password) { - w.Redirect(backlink+"/forgot?error=invalid&email=%s&secret=%s", email, secret) + w.Redirect(backlink + "/forgot?error=invalid&email=%s&secret=%s", email, secret) return } @@ -322,7 +322,7 @@ func userEditHandler(w *Web) { } if w.User.ID == user.ID { - w.Redirect(backlink+"/user/edit/%s", user.ID) + w.Redirect(backlink + "/user/edit/%s", user.ID) return } @@ -333,7 +333,7 @@ func userEditHandler(w *Web) { return nil }) - w.Redirect(backlink+"/user/edit/%s?success=edituser", user.ID) + w.Redirect(backlink + "/user/edit/%s?success=edituser", user.ID) } func userDeleteHandler(w *Web) { @@ -351,7 +351,7 @@ func userDeleteHandler(w *Web) { return } if w.User.ID == user.ID { - w.Redirect(backlink+"/user/edit/%s?error=deleteuser", user.ID) + w.Redirect(backlink + "/user/edit/%s?error=deleteuser", user.ID) return } @@ -531,7 +531,7 @@ WGCLIENT return } - w.Redirect(backlink+"/profile/connect/%s?success=addprofile", profile.ID) + w.Redirect(backlink + "/profile/connect/%s?success=addprofile", profile.ID) } func profileConnectHandler(w *Web) { @@ -574,7 +574,7 @@ func profileDeleteHandler(w *Web) { return } if len(profile.UserID) > 0 && w.Admin { - w.Redirect(backlink+"/user/edit/%s?success=deleteprofile", profile.UserID) + w.Redirect(backlink + "/user/edit/%s?success=deleteprofile", profile.UserID) return } w.Redirect(backlink + "?success=deleteprofile") From 6f3d62d9b877f8984a4b95e86e7c6e63bd1b9625 Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 06:59:01 +0800 Subject: [PATCH 18/36] patch: remove trailing slash from README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d59616d0..c0bb5a0b 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ $ subspace --http-host subspace.example.com | flag | default | description | | :-------------: | :-----: | :------------------------------------------------------------------------------------------------------------------------ | | `http-host` | | REQUIRED: The host to listen on and set cookies for | -| `backlink` | `/` | OPTIONAL: The page to set the home button to | +| `backlink` | `` | OPTIONAL: The page to set the home button to | | `datadir` | `/data` | OPTIONAL: The directory to store data such as the WireGuard configuration files | | `debug` | | OPTIONAL: Place subspace into debug mode for verbose log output | | `http-addr` | `:80` | OPTIONAL: HTTP listen address | From f5d2665c072973e94f841a4ecc4211d6083b0f9d Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 07:02:15 +0800 Subject: [PATCH 19/36] patch: improve the meaning of 'backlink' --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c0bb5a0b..bb96b5f2 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ $ subspace --http-host subspace.example.com | flag | default | description | | :-------------: | :-----: | :------------------------------------------------------------------------------------------------------------------------ | | `http-host` | | REQUIRED: The host to listen on and set cookies for | -| `backlink` | `` | OPTIONAL: The page to set the home button to | +| `backlink` | `` | OPTIONAL: The subdirectory that runs `subspace` | | `datadir` | `/data` | OPTIONAL: The directory to store data such as the WireGuard configuration files | | `debug` | | OPTIONAL: Place subspace into debug mode for verbose log output | | `http-addr` | `:80` | OPTIONAL: HTTP listen address | @@ -125,7 +125,7 @@ $ subspace --http-host subspace.example.com | `SUBSPACE_IPV4_NAT_ENABLED` | `true` | Whether to enable NAT routing for IPv4 | | `SUBSPACE_IPV6_NAT_ENABLED` | `true` | Whether to enable NAT routing for IPv6 | | `SUBSPACE_THEME` | `green` | The theme to use, please refer to [semantic-ui](https://semantic-ui.com/usage/theming.html) for accepted colors | -| `SUBSPACE_BACKLINK` | `/` | The page to set the home button to | +| `SUBSPACE_BACKLINK` | `/` | The subdirectory that runs `subspace` | | `SUBSPACE_DISABLE_DNS` | `false` | Whether to disable DNS so the client uses their own configured DNS server(s). Consider disabling DNS server, if supporting international VPN clients | ### Run as a Docker container From 197b81e321e46f0e33a4e676b388cd2a1335f52c Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 07:08:47 +0800 Subject: [PATCH 20/36] patch: completely rename 'backlink' to SubDirectory --- README.md | 4 +- cmd/subspace/handlers.go | 82 ++++++++++++++--------------- cmd/subspace/main.go | 84 +++++++++++++++--------------- cmd/subspace/web.go | 28 +++++----- entrypoint.sh | 6 +-- web/templates/configure.html | 2 +- web/templates/forgot.html | 2 +- web/templates/header.html | 26 ++++----- web/templates/index.html | 18 +++---- web/templates/profile/connect.html | 20 +++---- web/templates/profile/delete.html | 4 +- web/templates/settings.html | 18 +++---- web/templates/signin.html | 6 +-- web/templates/user/delete.html | 4 +- web/templates/user/edit.html | 10 ++-- 15 files changed, 157 insertions(+), 157 deletions(-) diff --git a/README.md b/README.md index bb96b5f2..6ff37f68 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ $ subspace --http-host subspace.example.com | flag | default | description | | :-------------: | :-----: | :------------------------------------------------------------------------------------------------------------------------ | | `http-host` | | REQUIRED: The host to listen on and set cookies for | -| `backlink` | `` | OPTIONAL: The subdirectory that runs `subspace` | +| `subdir` | `` | OPTIONAL: The subdirectory that runs `subspace` | | `datadir` | `/data` | OPTIONAL: The directory to store data such as the WireGuard configuration files | | `debug` | | OPTIONAL: Place subspace into debug mode for verbose log output | | `http-addr` | `:80` | OPTIONAL: HTTP listen address | @@ -125,7 +125,7 @@ $ subspace --http-host subspace.example.com | `SUBSPACE_IPV4_NAT_ENABLED` | `true` | Whether to enable NAT routing for IPv4 | | `SUBSPACE_IPV6_NAT_ENABLED` | `true` | Whether to enable NAT routing for IPv6 | | `SUBSPACE_THEME` | `green` | The theme to use, please refer to [semantic-ui](https://semantic-ui.com/usage/theming.html) for accepted colors | -| `SUBSPACE_BACKLINK` | `/` | The subdirectory that runs `subspace` | +| `SUBSPACE_URL_SUBDIRECTORY` | `/` | The subdirectory that runs `subspace` | | `SUBSPACE_DISABLE_DNS` | `false` | Whether to disable DNS so the client uses their own configured DNS server(s). Consider disabling DNS server, if supporting international VPN clients | ### Run as a Docker container diff --git a/cmd/subspace/handlers.go b/cmd/subspace/handlers.go index e9335585..2c264cf6 100644 --- a/cmd/subspace/handlers.go +++ b/cmd/subspace/handlers.go @@ -36,7 +36,7 @@ func getEnv(key, fallback string) string { func ssoHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { session, err := samlSP.Session.GetSession(r) if session != nil { - http.Redirect(w, r, backlink, http.StatusFound) + http.Redirect(w, r, subdir, http.StatusFound) return } if err == samlsp.ErrNoSession { @@ -120,7 +120,7 @@ func wireguardConfigHandler(w *Web) { func configureHandler(w *Web) { if config.FindInfo().Configured { - w.Redirect(backlink + "?error=configured") + w.Redirect(subdir + "?error=configured") return } @@ -134,13 +134,13 @@ func configureHandler(w *Web) { password := w.r.FormValue("password") if !validEmail.MatchString(email) || !validPassword.MatchString(password) || email != emailConfirm { - w.Redirect(backlink + "/configure?error=invalid") + w.Redirect(subdir + "/configure?error=invalid") return } hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { - w.Redirect(backlink + "/forgot?error=bcrypt") + w.Redirect(subdir + "/forgot?error=bcrypt") return } config.UpdateInfo(func(i *Info) error { @@ -154,7 +154,7 @@ func configureHandler(w *Web) { Error(w.w, err) return } - w.Redirect(backlink + "/settings?success=configured") + w.Redirect(subdir + "/settings?success=configured") } func forgotHandler(w *Web) { @@ -168,20 +168,20 @@ func forgotHandler(w *Web) { password := w.r.FormValue("password") if email != "" && !validEmail.MatchString(email) { - w.Redirect(backlink + "/forgot?error=invalid") + w.Redirect(subdir + "/forgot?error=invalid") return } if secret != "" && !validString.MatchString(secret) { - w.Redirect(backlink + "/forgot?error=invalid") + w.Redirect(subdir + "/forgot?error=invalid") return } if email != "" && secret != "" && !validPassword.MatchString(password) { - w.Redirect(backlink + "/forgot?error=invalid&email=%s&secret=%s", email, secret) + w.Redirect(subdir+"/forgot?error=invalid&email=%s&secret=%s", email, secret) return } if email != config.FindInfo().Email { - w.Redirect(backlink + "/forgot?error=invalid") + w.Redirect(subdir + "/forgot?error=invalid") return } @@ -203,18 +203,18 @@ func forgotHandler(w *Web) { } }() - w.Redirect(backlink + "/forgot?success=forgot") + w.Redirect(subdir + "/forgot?success=forgot") return } if secret != config.FindInfo().Secret { - w.Redirect(backlink + "/forgot?error=invalid") + w.Redirect(subdir + "/forgot?error=invalid") return } hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { - w.Redirect(backlink + "/forgot?error=bcrypt") + w.Redirect(subdir + "/forgot?error=bcrypt") return } config.UpdateInfo(func(i *Info) error { @@ -227,12 +227,12 @@ func forgotHandler(w *Web) { Error(w.w, err) return } - w.Redirect(backlink) + w.Redirect(subdir) } func signoutHandler(w *Web) { w.SignoutSession() - w.Redirect(backlink + "/signin") + w.Redirect(subdir + "/signin") } func signinHandler(w *Web) { @@ -246,18 +246,18 @@ func signinHandler(w *Web) { passcode := w.r.FormValue("totp") if email != config.FindInfo().Email { - w.Redirect(backlink + "/signin?error=invalid") + w.Redirect(subdir + "/signin?error=invalid") return } if err := bcrypt.CompareHashAndPassword(config.FindInfo().Password, []byte(password)); err != nil { - w.Redirect(backlink + "/signin?error=invalid") + w.Redirect(subdir + "/signin?error=invalid") return } if config.FindInfo().TotpKey != "" && !totp.Validate(passcode, config.FindInfo().TotpKey) { // Totp has been configured and the provided code doesn't match - w.Redirect(backlink + "/signin?error=invalid") + w.Redirect(subdir + "/signin?error=invalid") return } @@ -266,7 +266,7 @@ func signinHandler(w *Web) { return } - w.Redirect(backlink) + w.Redirect(subdir) } func totpQRHandler(w *Web) { @@ -277,7 +277,7 @@ func totpQRHandler(w *Web) { if config.Info.TotpKey != "" { // TOTP is already configured, don't allow the current one to be leaked - w.Redirect(backlink + "/") + w.Redirect(subdir + "/") return } @@ -322,7 +322,7 @@ func userEditHandler(w *Web) { } if w.User.ID == user.ID { - w.Redirect(backlink + "/user/edit/%s", user.ID) + w.Redirect(subdir+"/user/edit/%s", user.ID) return } @@ -333,7 +333,7 @@ func userEditHandler(w *Web) { return nil }) - w.Redirect(backlink + "/user/edit/%s?success=edituser", user.ID) + w.Redirect(subdir+"/user/edit/%s?success=edituser", user.ID) } func userDeleteHandler(w *Web) { @@ -351,7 +351,7 @@ func userDeleteHandler(w *Web) { return } if w.User.ID == user.ID { - w.Redirect(backlink + "/user/edit/%s?error=deleteuser", user.ID) + w.Redirect(subdir+"/user/edit/%s?error=deleteuser", user.ID) return } @@ -364,7 +364,7 @@ func userDeleteHandler(w *Web) { for _, profile := range config.ListProfilesByUser(user.ID) { if err := deleteProfile(profile); err != nil { logger.Errorf("delete profile failed: %s", err) - w.Redirect(backlink + "/profile/delete?error=deleteprofile") + w.Redirect(subdir + "/profile/delete?error=deleteprofile") return } } @@ -373,7 +373,7 @@ func userDeleteHandler(w *Web) { Error(w.w, err) return } - w.Redirect(backlink + "?success=deleteuser") + w.Redirect(subdir + "?success=deleteuser") } func profileAddHandler(w *Web) { @@ -391,7 +391,7 @@ func profileAddHandler(w *Web) { } if name == "" { - w.Redirect(backlink + "?error=profilename") + w.Redirect(subdir + "?error=profilename") return } @@ -403,14 +403,14 @@ func profileAddHandler(w *Web) { } if len(config.ListProfiles()) >= maxProfiles { - w.Redirect(backlink + "?error=addprofile") + w.Redirect(subdir + "?error=addprofile") return } profile, err := config.AddProfile(userID, name, platform) if err != nil { logger.Warn(err) - w.Redirect(backlink + "?error=addprofile") + w.Redirect(subdir + "?error=addprofile") return } @@ -527,11 +527,11 @@ WGCLIENT f, _ := os.Create("/tmp/error.txt") errstr := fmt.Sprintln(err) f.WriteString(errstr) - w.Redirect(backlink + "?error=addprofile") + w.Redirect(subdir + "?error=addprofile") return } - w.Redirect(backlink + "/profile/connect/%s?success=addprofile", profile.ID) + w.Redirect(subdir+"/profile/connect/%s?success=addprofile", profile.ID) } func profileConnectHandler(w *Web) { @@ -570,18 +570,18 @@ func profileDeleteHandler(w *Web) { } if err := deleteProfile(profile); err != nil { logger.Errorf("delete profile failed: %s", err) - w.Redirect(backlink + "/profile/delete?error=deleteprofile") + w.Redirect(subdir + "/profile/delete?error=deleteprofile") return } if len(profile.UserID) > 0 && w.Admin { - w.Redirect(backlink + "/user/edit/%s?success=deleteprofile", profile.UserID) + w.Redirect(subdir+"/user/edit/%s?success=deleteprofile", profile.UserID) return } - w.Redirect(backlink + "?success=deleteprofile") + w.Redirect(subdir + "?success=deleteprofile") } func indexHandler(w *Web) { - w.Redirect(backlink) + w.Redirect(subdir) } func rootIndexHandler(w *Web) { @@ -627,7 +627,7 @@ func settingsHandler(w *Web) { if len(samlMetadata) > 0 { if err := configureSAML(); err != nil { logger.Warnf("configuring SAML failed: %s", err) - w.Redirect(backlink + "/settings?error=saml") + w.Redirect(subdir + "/settings?error=saml") } } else { samlSP = nil @@ -635,18 +635,18 @@ func settingsHandler(w *Web) { if currentPassword != "" || newPassword != "" { if !validPassword.MatchString(newPassword) { - w.Redirect(backlink + "/settings?error=invalid") + w.Redirect(subdir + "/settings?error=invalid") return } if err := bcrypt.CompareHashAndPassword(config.FindInfo().Password, []byte(currentPassword)); err != nil { - w.Redirect(backlink + "/settings?error=invalid") + w.Redirect(subdir + "/settings?error=invalid") return } hashedPassword, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost) if err != nil { - w.Redirect(backlink + "/settings?error=bcrypt") + w.Redirect(subdir + "/settings?error=bcrypt") return } @@ -659,24 +659,24 @@ func settingsHandler(w *Web) { if resetTotp == "true" { err := config.ResetTotp() if err != nil { - w.Redirect(backlink + "/settings?error=totp") + w.Redirect(subdir + "/settings?error=totp") return } - w.Redirect(backlink + "/settings?success=totp") + w.Redirect(subdir + "/settings?success=totp") return } if config.Info.TotpKey == "" && totpCode != "" { if !totp.Validate(totpCode, tempTotpKey.Secret()) { - w.Redirect(backlink + "/settings?error=totp") + w.Redirect(subdir + "/settings?error=totp") return } config.Info.TotpKey = tempTotpKey.Secret() config.save() } - w.Redirect(backlink + "/settings?success=settings") + w.Redirect(subdir + "/settings?success=settings") } func helpHandler(w *Web) { diff --git a/cmd/subspace/main.go b/cmd/subspace/main.go index b10c7b2c..1ce0f5d7 100644 --- a/cmd/subspace/main.go +++ b/cmd/subspace/main.go @@ -45,8 +45,8 @@ var ( // Insecure http cookies (only recommended for internal LANs/VPNs) httpInsecure bool - // backlink - backlink string + // subdir + subdir string // show version showVersion bool @@ -87,7 +87,7 @@ var ( func init() { cli.StringVar(&datadir, "datadir", "/data", "data dir") - cli.StringVar(&backlink, "backlink", "", "backlink, without trailing slash (optional)") + cli.StringVar(&subdir, "subdir", "", "subdir, without trailing slash (optional)") cli.StringVar(&httpHost, "http-host", "", "HTTP host") cli.StringVar(&httpAddr, "http-addr", ":80", "HTTP listen address") cli.BoolVar(&httpInsecure, "http-insecure", false, "enable sessions cookies for http (no https) not recommended") @@ -169,42 +169,42 @@ func main() { // r := &httprouter.Router{} - r.GET(backlink, Log(WebHandler(rootIndexHandler, "index"))) - r.GET(backlink + "/", Log(WebHandler(indexHandler, "index"))) - r.GET(backlink + "/help", Log(WebHandler(helpHandler, "help"))) - r.GET(backlink + "/configure", Log(WebHandler(configureHandler, "configure"))) - r.POST(backlink + "/configure", Log(WebHandler(configureHandler, "configure"))) + r.GET(subdir, Log(WebHandler(rootIndexHandler, "index"))) + r.GET(subdir+"/", Log(WebHandler(indexHandler, "index"))) + r.GET(subdir+"/help", Log(WebHandler(helpHandler, "help"))) + r.GET(subdir+"/configure", Log(WebHandler(configureHandler, "configure"))) + r.POST(subdir+"/configure", Log(WebHandler(configureHandler, "configure"))) // SAML - r.GET(backlink + "/sso", Log(ssoHandler)) - r.GET(backlink + "/saml/metadata", Log(samlHandler)) - r.POST(backlink + "/saml/metadata", Log(samlHandler)) - r.GET(backlink + "/saml/acs", Log(samlHandler)) - r.POST(backlink + "/saml/acs", Log(samlHandler)) - - r.GET(backlink + "/totp/image", Log(WebHandler(totpQRHandler, "totp/image"))) - r.GET(backlink + "/signin", Log(WebHandler(signinHandler, "signin"))) - r.GET(backlink + "/signout", Log(WebHandler(signoutHandler, "signout"))) - r.POST(backlink + "/signin", Log(WebHandler(signinHandler, "signin"))) - r.GET(backlink + "/forgot", Log(WebHandler(forgotHandler, "forgot"))) - r.POST(backlink + "/forgot", Log(WebHandler(forgotHandler, "forgot"))) - - r.GET(backlink + "/settings", Log(WebHandler(settingsHandler, "settings"))) - r.POST(backlink + "/settings", Log(WebHandler(settingsHandler, "settings"))) - - r.GET(backlink + "/user/edit/:user", Log(WebHandler(userEditHandler, "user/edit"))) - r.POST(backlink + "/user/edit", Log(WebHandler(userEditHandler, "user/edit"))) - r.GET(backlink + "/user/delete/:user", Log(WebHandler(userDeleteHandler, "user/delete"))) - r.POST(backlink + "/user/delete", Log(WebHandler(userDeleteHandler, "user/delete"))) - - r.GET(backlink + "/profile/add", Log(WebHandler(profileAddHandler, "profile/add"))) - r.POST(backlink + "/profile/add", Log(WebHandler(profileAddHandler, "profile/add"))) - r.GET(backlink + "/profile/connect/:profile", Log(WebHandler(profileConnectHandler, "profile/connect"))) - r.GET(backlink + "/profile/delete/:profile", Log(WebHandler(profileDeleteHandler, "profile/delete"))) - r.POST(backlink + "/profile/delete", Log(WebHandler(profileDeleteHandler, "profile/delete"))) - r.GET(backlink + "/profile/config/wireguard/:profile", Log(WebHandler(wireguardConfigHandler, "profile/config/wireguard"))) - r.GET(backlink + "/profile/qrconfig/wireguard/:profile", Log(WebHandler(wireguardQRConfigHandler, "profile/qrconfig/wireguard"))) - r.GET(backlink + "/static/*path", staticHandler) + r.GET(subdir+"/sso", Log(ssoHandler)) + r.GET(subdir+"/saml/metadata", Log(samlHandler)) + r.POST(subdir+"/saml/metadata", Log(samlHandler)) + r.GET(subdir+"/saml/acs", Log(samlHandler)) + r.POST(subdir+"/saml/acs", Log(samlHandler)) + + r.GET(subdir+"/totp/image", Log(WebHandler(totpQRHandler, "totp/image"))) + r.GET(subdir+"/signin", Log(WebHandler(signinHandler, "signin"))) + r.GET(subdir+"/signout", Log(WebHandler(signoutHandler, "signout"))) + r.POST(subdir+"/signin", Log(WebHandler(signinHandler, "signin"))) + r.GET(subdir+"/forgot", Log(WebHandler(forgotHandler, "forgot"))) + r.POST(subdir+"/forgot", Log(WebHandler(forgotHandler, "forgot"))) + + r.GET(subdir+"/settings", Log(WebHandler(settingsHandler, "settings"))) + r.POST(subdir+"/settings", Log(WebHandler(settingsHandler, "settings"))) + + r.GET(subdir+"/user/edit/:user", Log(WebHandler(userEditHandler, "user/edit"))) + r.POST(subdir+"/user/edit", Log(WebHandler(userEditHandler, "user/edit"))) + r.GET(subdir+"/user/delete/:user", Log(WebHandler(userDeleteHandler, "user/delete"))) + r.POST(subdir+"/user/delete", Log(WebHandler(userDeleteHandler, "user/delete"))) + + r.GET(subdir+"/profile/add", Log(WebHandler(profileAddHandler, "profile/add"))) + r.POST(subdir+"/profile/add", Log(WebHandler(profileAddHandler, "profile/add"))) + r.GET(subdir+"/profile/connect/:profile", Log(WebHandler(profileConnectHandler, "profile/connect"))) + r.GET(subdir+"/profile/delete/:profile", Log(WebHandler(profileDeleteHandler, "profile/delete"))) + r.POST(subdir+"/profile/delete", Log(WebHandler(profileDeleteHandler, "profile/delete"))) + r.GET(subdir+"/profile/config/wireguard/:profile", Log(WebHandler(wireguardConfigHandler, "profile/config/wireguard"))) + r.GET(subdir+"/profile/qrconfig/wireguard/:profile", Log(WebHandler(wireguardQRConfigHandler, "profile/qrconfig/wireguard"))) + r.GET(subdir+"/static/*path", staticHandler) // // Server @@ -227,12 +227,12 @@ func main() { hostport = httpHost } if len(httpIP) == 0 { - hostport = "[::]:" + httpPort + hostport = "[::]:" + httpPort } logger.Infof("Subspace version: %s %s", version, &url.URL{ Scheme: "http", Host: hostport, - Path: backlink, + Path: subdir, }) logger.Fatal(httpd.ListenAndServe()) } @@ -258,7 +258,7 @@ func main() { // http redirect to https and Let's Encrypt auth go func() { redir := httprouter.New() - redir.GET(backlink + "/*path", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { + redir.GET(subdir+"/*path", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { r.URL.Scheme = "https" r.URL.Host = httpHost http.Redirect(w, r, r.URL.String(), http.StatusFound) @@ -326,7 +326,7 @@ func main() { logger.Infof("Subspace version: %s %s", version, &url.URL{ Scheme: "https", Host: hostport, - Path: backlink, + Path: subdir, }) logger.Fatal(httpsd.Serve(tlsListener)) } @@ -385,7 +385,7 @@ func configureSAML() error { rootURL := url.URL{ Scheme: "https", Host: httpHost, - Path: backlink, + Path: subdir, } if httpInsecure { diff --git a/cmd/subspace/web.go b/cmd/subspace/web.go index 735a41db..d8159d8b 100644 --- a/cmd/subspace/web.go +++ b/cmd/subspace/web.go @@ -41,14 +41,14 @@ type Web struct { template string // Default - Backlink string - Version string - Request *http.Request - Section string - Time time.Time - Info Info - Admin bool - SAML *samlsp.Middleware + SubDirectory string + Version string + Request *http.Request + Section string + Time time.Time + Info Info + Admin bool + SAML *samlsp.Middleware User User Users []User @@ -153,7 +153,7 @@ func WebHandler(h func(*Web), section string) httprouter.Handle { ps: ps, template: section + ".html", - Backlink: backlink, + SubDirectory: subdir, Time: time.Now(), Version: version, Request: r, @@ -165,7 +165,7 @@ func WebHandler(h func(*Web), section string) httprouter.Handle { } if !config.FindInfo().Configured { - web.Redirect(backlink + "/configure") + web.Redirect(subdir + "/configure") return } @@ -243,7 +243,7 @@ func WebHandler(h func(*Web), section string) httprouter.Handle { } logger.Warnf("auth: sign in required") - web.Redirect(backlink + "/signin") + web.Redirect(subdir + "/signin") } } @@ -304,7 +304,7 @@ func (w *Web) SignoutSession() { http.SetCookie(w.w, &http.Cookie{ Name: SessionCookieNameSSO, Value: "", - Path: backlink, + Path: subdir, HttpOnly: true, Domain: httpHost, Secure: !httpInsecure, @@ -315,7 +315,7 @@ func (w *Web) SignoutSession() { http.SetCookie(w.w, &http.Cookie{ Name: SessionCookieName, Value: "", - Path: backlink, + Path: subdir, HttpOnly: true, Domain: httpHost, Secure: !httpInsecure, @@ -339,7 +339,7 @@ func (w *Web) SigninSession(admin bool, userID string) error { http.SetCookie(w.w, &http.Cookie{ Name: SessionCookieName, Value: encoded, - Path: backlink, + Path: subdir, HttpOnly: true, Domain: httpHost, Secure: !httpInsecure, diff --git a/entrypoint.sh b/entrypoint.sh index 57d89e05..5a3f2211 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -10,8 +10,8 @@ if [ -z "${SUBSPACE_HTTP_HOST-}" ]; then exit 1 fi # Optional environment variables. -if [ -z "${SUBSPACE_BACKLINK-}" ]; then - export SUBSPACE_BACKLINK="" +if [ -z "${SUBSPACE_URL_SUBDIRECTORY-}" ]; then + export SUBSPACE_URL_SUBDIRECTORY="" fi if [ -z "${SUBSPACE_IPV4_POOL-}" ]; then @@ -240,7 +240,7 @@ exec /usr/bin/subspace \ "--http-host=${SUBSPACE_HTTP_HOST}" \ "--http-addr=${SUBSPACE_HTTP_ADDR}" \ "--http-insecure=${SUBSPACE_HTTP_INSECURE}" \ - "--backlink=${SUBSPACE_BACKLINK}" \ + "--subdir=${SUBSPACE_URL_SUBDIRECTORY}" \ "--letsencrypt=${SUBSPACE_LETSENCRYPT}" \ "--theme=${SUBSPACE_THEME}" RUNIT diff --git a/web/templates/configure.html b/web/templates/configure.html index d1409f52..fad8a9d7 100644 --- a/web/templates/configure.html +++ b/web/templates/configure.html @@ -34,7 +34,7 @@ -
+
Email Address
diff --git a/web/templates/forgot.html b/web/templates/forgot.html index 58bc9b3a..f262031e 100644 --- a/web/templates/forgot.html +++ b/web/templates/forgot.html @@ -40,7 +40,7 @@ {{$email := $.Request.FormValue "email"}} {{$secret := $.Request.FormValue "secret"}} - + {{if and $email $secret}} diff --git a/web/templates/header.html b/web/templates/header.html index d68cb92a..95d15df3 100644 --- a/web/templates/header.html +++ b/web/templates/header.html @@ -5,28 +5,28 @@ - - + + Subspace - - - + + + - - + + - +
{{end}} {{with $error := $.Request.FormValue "error"}} @@ -30,7 +30,7 @@ {{$error}} {{end}}
- +
@@ -47,7 +47,7 @@
- +
@@ -104,7 +104,7 @@
{{range $n, $p := $.TargetProfiles}}
- + {{end}} @@ -164,7 +164,7 @@
{{range $n, $p := $.Profiles}}
- + {{end}} @@ -222,7 +222,7 @@
{{range $n, $u := $.Users}}
- +
@@ -256,7 +256,7 @@
{{end}} diff --git a/web/templates/profile/connect.html b/web/templates/profile/connect.html index efe3350b..ee873124 100644 --- a/web/templates/profile/connect.html +++ b/web/templates/profile/connect.html @@ -1,7 +1,7 @@ {{template "header.html" .}}
- Back + Back {{with $success := $.Request.FormValue "success"}} @@ -14,7 +14,7 @@ {{$success}} {{end}}
- +
@@ -39,7 +39,7 @@
- Download your WireGuard config and import it into WireGuard + Download your WireGuard config and import it into WireGuard
@@ -59,7 +59,7 @@
- Download your WireGuard config into your Downloads folder + Download your WireGuard config into your Downloads folder
@@ -119,7 +119,7 @@
- Download your WireGuard config and open with WireGuard or use the QR code below + Download your WireGuard config and open with WireGuard or use the QR code below
@@ -142,7 +142,7 @@
- qr-code could not be displayed + qr-code could not be displayed {{else if eq $.Profile.Platform "android"}}
Android — Instructions
@@ -159,7 +159,7 @@
- Download your WireGuard config or use the QR code below + Download your WireGuard config or use the QR code below
@@ -174,7 +174,7 @@
- qr-code could not be displayed + qr-code could not be displayed {{else if eq $.Profile.Platform "linux"}}
Linux — Instructions
@@ -191,7 +191,7 @@
@@ -219,7 +219,7 @@
diff --git a/web/templates/profile/delete.html b/web/templates/profile/delete.html index 8c9daf4d..27cfe78a 100644 --- a/web/templates/profile/delete.html +++ b/web/templates/profile/delete.html @@ -12,10 +12,10 @@ - +
- Cancel + Cancel
diff --git a/web/templates/settings.html b/web/templates/settings.html index 20a44532..b07577ef 100644 --- a/web/templates/settings.html +++ b/web/templates/settings.html @@ -17,7 +17,7 @@ TOTP reset for default user, please reconfigure for improved security. {{end}} - + {{end}} @@ -39,7 +39,7 @@ {{end}} -
+
Single Sign-On (SAML)
@@ -55,11 +55,11 @@
Your ACS URL
- +
Your Entity ID
- +
IDP Metadata
@@ -70,7 +70,7 @@
- Cancel + Cancel
@@ -97,7 +97,7 @@
- Cancel + Cancel
@@ -113,7 +113,7 @@
- Cancel + Cancel
@@ -125,7 +125,7 @@
Secret: {{$.TempTotpKey.Secret}}
- TOTP qr-code could not be displayed + TOTP qr-code could not be displayed
@@ -137,7 +137,7 @@
- Cancel + Cancel
diff --git a/web/templates/signin.html b/web/templates/signin.html index 8eed40d6..5ce7a193 100644 --- a/web/templates/signin.html +++ b/web/templates/signin.html @@ -25,7 +25,7 @@ {{$ssoprovider := ssoprovider}} - {{if eq $ssoprovider "Google"}}{{end}}Sign in with {{$ssoprovider}} + {{if eq $ssoprovider "Google"}}{{end}}Sign in with {{$ssoprovider}} @@ -33,7 +33,7 @@
Admin Sign In
- +
@@ -59,7 +59,7 @@ diff --git a/web/templates/user/delete.html b/web/templates/user/delete.html index d4d3ddaf..6d242475 100644 --- a/web/templates/user/delete.html +++ b/web/templates/user/delete.html @@ -12,10 +12,10 @@
-
+
- Cancel + Cancel
diff --git a/web/templates/user/edit.html b/web/templates/user/edit.html index 655df623..1cee4007 100644 --- a/web/templates/user/edit.html +++ b/web/templates/user/edit.html @@ -1,7 +1,7 @@ {{template "header.html" .}}
- Back + Back
@@ -14,7 +14,7 @@
{{range $n, $p := $.Profiles}}
- + {{end}} @@ -66,7 +66,7 @@
-
+
@@ -77,7 +77,7 @@ {{end}}
From 1e038c46ab3904c0ccb86a58cec8d2fccc970b3c Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 07:10:40 +0800 Subject: [PATCH 21/36] fix: remove trailing slash from subdir in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6ff37f68..ccb92e93 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ $ subspace --http-host subspace.example.com | `SUBSPACE_IPV4_NAT_ENABLED` | `true` | Whether to enable NAT routing for IPv4 | | `SUBSPACE_IPV6_NAT_ENABLED` | `true` | Whether to enable NAT routing for IPv6 | | `SUBSPACE_THEME` | `green` | The theme to use, please refer to [semantic-ui](https://semantic-ui.com/usage/theming.html) for accepted colors | -| `SUBSPACE_URL_SUBDIRECTORY` | `/` | The subdirectory that runs `subspace` | +| `SUBSPACE_URL_SUBDIRECTORY` | `` | The subdirectory that runs `subspace` | | `SUBSPACE_DISABLE_DNS` | `false` | Whether to disable DNS so the client uses their own configured DNS server(s). Consider disabling DNS server, if supporting international VPN clients | ### Run as a Docker container From 6c5e88e0a0eb49c14de99712b9efb72fdee45e38 Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 07:13:52 +0800 Subject: [PATCH 22/36] patch: reword subdir argument flag for cli --- cmd/subspace/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/subspace/main.go b/cmd/subspace/main.go index 1ce0f5d7..d371dde4 100644 --- a/cmd/subspace/main.go +++ b/cmd/subspace/main.go @@ -87,7 +87,7 @@ var ( func init() { cli.StringVar(&datadir, "datadir", "/data", "data dir") - cli.StringVar(&subdir, "subdir", "", "subdir, without trailing slash (optional)") + cli.StringVar(&subdir, "subdir", "", "[optional] URL path(without hostname) to subspace instance, without trailing slash") cli.StringVar(&httpHost, "http-host", "", "HTTP host") cli.StringVar(&httpAddr, "http-addr", ":80", "HTTP listen address") cli.BoolVar(&httpInsecure, "http-insecure", false, "enable sessions cookies for http (no https) not recommended") From 9d646ea991a2368b2a653da9f4802f455a49fc94 Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 07:15:08 +0800 Subject: [PATCH 23/36] fix: spacing issue in main.go --- cmd/subspace/main.go | 68 ++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/cmd/subspace/main.go b/cmd/subspace/main.go index d371dde4..3b9a3540 100644 --- a/cmd/subspace/main.go +++ b/cmd/subspace/main.go @@ -170,41 +170,41 @@ func main() { r := &httprouter.Router{} r.GET(subdir, Log(WebHandler(rootIndexHandler, "index"))) - r.GET(subdir+"/", Log(WebHandler(indexHandler, "index"))) - r.GET(subdir+"/help", Log(WebHandler(helpHandler, "help"))) - r.GET(subdir+"/configure", Log(WebHandler(configureHandler, "configure"))) - r.POST(subdir+"/configure", Log(WebHandler(configureHandler, "configure"))) + r.GET(subdir + "/", Log(WebHandler(indexHandler, "index"))) + r.GET(subdir + "/help", Log(WebHandler(helpHandler, "help"))) + r.GET(subdir + "/configure", Log(WebHandler(configureHandler, "configure"))) + r.POST(subdir + "/configure", Log(WebHandler(configureHandler, "configure"))) // SAML - r.GET(subdir+"/sso", Log(ssoHandler)) - r.GET(subdir+"/saml/metadata", Log(samlHandler)) - r.POST(subdir+"/saml/metadata", Log(samlHandler)) - r.GET(subdir+"/saml/acs", Log(samlHandler)) - r.POST(subdir+"/saml/acs", Log(samlHandler)) - - r.GET(subdir+"/totp/image", Log(WebHandler(totpQRHandler, "totp/image"))) - r.GET(subdir+"/signin", Log(WebHandler(signinHandler, "signin"))) - r.GET(subdir+"/signout", Log(WebHandler(signoutHandler, "signout"))) - r.POST(subdir+"/signin", Log(WebHandler(signinHandler, "signin"))) - r.GET(subdir+"/forgot", Log(WebHandler(forgotHandler, "forgot"))) - r.POST(subdir+"/forgot", Log(WebHandler(forgotHandler, "forgot"))) - - r.GET(subdir+"/settings", Log(WebHandler(settingsHandler, "settings"))) - r.POST(subdir+"/settings", Log(WebHandler(settingsHandler, "settings"))) - - r.GET(subdir+"/user/edit/:user", Log(WebHandler(userEditHandler, "user/edit"))) - r.POST(subdir+"/user/edit", Log(WebHandler(userEditHandler, "user/edit"))) - r.GET(subdir+"/user/delete/:user", Log(WebHandler(userDeleteHandler, "user/delete"))) - r.POST(subdir+"/user/delete", Log(WebHandler(userDeleteHandler, "user/delete"))) - - r.GET(subdir+"/profile/add", Log(WebHandler(profileAddHandler, "profile/add"))) - r.POST(subdir+"/profile/add", Log(WebHandler(profileAddHandler, "profile/add"))) - r.GET(subdir+"/profile/connect/:profile", Log(WebHandler(profileConnectHandler, "profile/connect"))) - r.GET(subdir+"/profile/delete/:profile", Log(WebHandler(profileDeleteHandler, "profile/delete"))) - r.POST(subdir+"/profile/delete", Log(WebHandler(profileDeleteHandler, "profile/delete"))) - r.GET(subdir+"/profile/config/wireguard/:profile", Log(WebHandler(wireguardConfigHandler, "profile/config/wireguard"))) - r.GET(subdir+"/profile/qrconfig/wireguard/:profile", Log(WebHandler(wireguardQRConfigHandler, "profile/qrconfig/wireguard"))) - r.GET(subdir+"/static/*path", staticHandler) + r.GET(subdir + "/sso", Log(ssoHandler)) + r.GET(subdir + "/saml/metadata", Log(samlHandler)) + r.POST(subdir + "/saml/metadata", Log(samlHandler)) + r.GET(subdir + "/saml/acs", Log(samlHandler)) + r.POST(subdir + "/saml/acs", Log(samlHandler)) + + r.GET(subdir + "/totp/image", Log(WebHandler(totpQRHandler, "totp/image"))) + r.GET(subdir + "/signin", Log(WebHandler(signinHandler, "signin"))) + r.GET(subdir + "/signout", Log(WebHandler(signoutHandler, "signout"))) + r.POST(subdir + "/signin", Log(WebHandler(signinHandler, "signin"))) + r.GET(subdir + "/forgot", Log(WebHandler(forgotHandler, "forgot"))) + r.POST(subdir + "/forgot", Log(WebHandler(forgotHandler, "forgot"))) + + r.GET(subdir + "/settings", Log(WebHandler(settingsHandler, "settings"))) + r.POST(subdir + "/settings", Log(WebHandler(settingsHandler, "settings"))) + + r.GET(subdir + "/user/edit/:user", Log(WebHandler(userEditHandler, "user/edit"))) + r.POST(subdir + "/user/edit", Log(WebHandler(userEditHandler, "user/edit"))) + r.GET(subdir + "/user/delete/:user", Log(WebHandler(userDeleteHandler, "user/delete"))) + r.POST(subdir + "/user/delete", Log(WebHandler(userDeleteHandler, "user/delete"))) + + r.GET(subdir + "/profile/add", Log(WebHandler(profileAddHandler, "profile/add"))) + r.POST(subdir + "/profile/add", Log(WebHandler(profileAddHandler, "profile/add"))) + r.GET(subdir + "/profile/connect/:profile", Log(WebHandler(profileConnectHandler, "profile/connect"))) + r.GET(subdir + "/profile/delete/:profile", Log(WebHandler(profileDeleteHandler, "profile/delete"))) + r.POST(subdir + "/profile/delete", Log(WebHandler(profileDeleteHandler, "profile/delete"))) + r.GET(subdir + "/profile/config/wireguard/:profile", Log(WebHandler(wireguardConfigHandler, "profile/config/wireguard"))) + r.GET(subdir + "/profile/qrconfig/wireguard/:profile", Log(WebHandler(wireguardQRConfigHandler, "profile/qrconfig/wireguard"))) + r.GET(subdir + "/static/*path", staticHandler) // // Server @@ -258,7 +258,7 @@ func main() { // http redirect to https and Let's Encrypt auth go func() { redir := httprouter.New() - redir.GET(subdir+"/*path", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { + redir.GET(subdir + "/*path", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { r.URL.Scheme = "https" r.URL.Host = httpHost http.Redirect(w, r, r.URL.String(), http.StatusFound) From 6905f420f0d8187b8c043f839b0e748c9b6714b9 Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 07:16:12 +0800 Subject: [PATCH 24/36] fix: spacing issue (again) in handlers.go --- cmd/subspace/handlers.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd/subspace/handlers.go b/cmd/subspace/handlers.go index 2c264cf6..beb1218c 100644 --- a/cmd/subspace/handlers.go +++ b/cmd/subspace/handlers.go @@ -176,7 +176,7 @@ func forgotHandler(w *Web) { return } if email != "" && secret != "" && !validPassword.MatchString(password) { - w.Redirect(subdir+"/forgot?error=invalid&email=%s&secret=%s", email, secret) + w.Redirect(subdir + "/forgot?error=invalid&email=%s&secret=%s", email, secret) return } @@ -322,7 +322,7 @@ func userEditHandler(w *Web) { } if w.User.ID == user.ID { - w.Redirect(subdir+"/user/edit/%s", user.ID) + w.Redirect(subdir + "/user/edit/%s", user.ID) return } @@ -333,7 +333,7 @@ func userEditHandler(w *Web) { return nil }) - w.Redirect(subdir+"/user/edit/%s?success=edituser", user.ID) + w.Redirect(subdir + "/user/edit/%s?success=edituser", user.ID) } func userDeleteHandler(w *Web) { @@ -351,7 +351,7 @@ func userDeleteHandler(w *Web) { return } if w.User.ID == user.ID { - w.Redirect(subdir+"/user/edit/%s?error=deleteuser", user.ID) + w.Redirect(subdir + "/user/edit/%s?error=deleteuser", user.ID) return } @@ -531,7 +531,7 @@ WGCLIENT return } - w.Redirect(subdir+"/profile/connect/%s?success=addprofile", profile.ID) + w.Redirect(subdir + "/profile/connect/%s?success=addprofile", profile.ID) } func profileConnectHandler(w *Web) { @@ -574,7 +574,7 @@ func profileDeleteHandler(w *Web) { return } if len(profile.UserID) > 0 && w.Admin { - w.Redirect(subdir+"/user/edit/%s?success=deleteprofile", profile.UserID) + w.Redirect(subdir + "/user/edit/%s?success=deleteprofile", profile.UserID) return } w.Redirect(subdir + "?success=deleteprofile") From bbe8e29b802d2375335a007f4ef0e2914f79a143 Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Mon, 21 Jun 2021 07:21:06 +0800 Subject: [PATCH 25/36] revert a8e448d: keep trailing slash for homepage This is in case the subdir variable is empty, which could render the navigation link href empty. --- web/templates/header.html | 4 ++-- web/templates/index.html | 4 ++-- web/templates/profile/connect.html | 2 +- web/templates/profile/delete.html | 2 +- web/templates/settings.html | 8 ++++---- web/templates/user/edit.html | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/web/templates/header.html b/web/templates/header.html index 95d15df3..c59c2b75 100644 --- a/web/templates/header.html +++ b/web/templates/header.html @@ -22,9 +22,9 @@ {{end}} {{with $error := $.Request.FormValue "error"}} @@ -30,7 +30,7 @@ {{$error}} {{end}}
- +
diff --git a/web/templates/profile/connect.html b/web/templates/profile/connect.html index ee873124..e4c75ff6 100644 --- a/web/templates/profile/connect.html +++ b/web/templates/profile/connect.html @@ -1,7 +1,7 @@ {{template "header.html" .}}
- Back + Back {{with $success := $.Request.FormValue "success"}} diff --git a/web/templates/profile/delete.html b/web/templates/profile/delete.html index 27cfe78a..2e7a2bb1 100644 --- a/web/templates/profile/delete.html +++ b/web/templates/profile/delete.html @@ -15,7 +15,7 @@
- Cancel + Cancel
diff --git a/web/templates/settings.html b/web/templates/settings.html index b07577ef..3848c3c3 100644 --- a/web/templates/settings.html +++ b/web/templates/settings.html @@ -70,7 +70,7 @@
- Cancel + Cancel
@@ -97,7 +97,7 @@
- Cancel + Cancel
@@ -113,7 +113,7 @@
- Cancel + Cancel
@@ -137,7 +137,7 @@
- Cancel + Cancel
diff --git a/web/templates/user/edit.html b/web/templates/user/edit.html index 1cee4007..9100cc8f 100644 --- a/web/templates/user/edit.html +++ b/web/templates/user/edit.html @@ -1,7 +1,7 @@ {{template "header.html" .}}
- Back + Back
From cbd352401369ccfbb2e0fd3dafac43108688d480 Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Sat, 9 Oct 2021 15:36:39 +0800 Subject: [PATCH 26/36] =?UTF-8?q?=F0=9F=92=A2=20patch:=20add=20backward=20?= =?UTF-8?q?compatibility=20and=20startup=20delay=20for=20using=20deprecate?= =?UTF-8?q?d=20flags?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/subspace/main.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cmd/subspace/main.go b/cmd/subspace/main.go index 3b9a3540..06f98128 100644 --- a/cmd/subspace/main.go +++ b/cmd/subspace/main.go @@ -47,6 +47,7 @@ var ( // subdir subdir string + backlink string // show version showVersion bool @@ -87,6 +88,7 @@ var ( func init() { cli.StringVar(&datadir, "datadir", "/data", "data dir") + cli.StringVar(&backlink, "backlink", "", "[deprecated] Please use `--subdir` for directory path prefix to the subspace instance.") cli.StringVar(&subdir, "subdir", "", "[optional] URL path(without hostname) to subspace instance, without trailing slash") cli.StringVar(&httpHost, "http-host", "", "HTTP host") cli.StringVar(&httpAddr, "http-addr", ":80", "HTTP listen address") @@ -120,6 +122,16 @@ func main() { os.Exit(0) } + // show warning message if deprecated flags are used + if backlink != "" { + subdir = backlink + logger.Warnf("You are using a deprecated flag `backlink`, and it will be removed in a future release.\nPlease kindly change the flag to `subdir` to avoid your installation being broken in future updates.") + + // sleep for 10 seconds before continue initializing + logger.Error("[WARNING] Deprecated flag `backlink` detected, giving a 90 seconds startup delay...") + time.Sleep(90 * time.Second) + } + // http host if httpHost == "" { usage("--http-host flag is required") From e01abb139ca772d811e5e57d7baba36ca507d6d1 Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Sat, 9 Oct 2021 15:37:25 +0800 Subject: [PATCH 27/36] =?UTF-8?q?=F0=9F=94=AE=20patch:=20Dockerfile=20to?= =?UTF-8?q?=20always=20build=20with=20latest=20golang=20and=20alpine=20ima?= =?UTF-8?q?ges?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 5c7aab14..a029c511 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.16-alpine as build +FROM golang:alpine as build RUN apk add --no-cache \ git \ @@ -18,7 +18,7 @@ ENV GODEBUG="netdns=go http2server=0" RUN make build BUILD_VERSION=${BUILD_VERSION} -FROM alpine:3.13.4 +FROM alpine:latest LABEL maintainer="github.com/subspacecommunity/subspace" COPY --from=build /src/subspace /usr/bin/subspace From d74e07429eac7a1de4082dcacf8763abe84b3809 Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Sat, 9 Oct 2021 15:40:26 +0800 Subject: [PATCH 28/36] =?UTF-8?q?=F0=9F=8F=BA=20revert:=20old=20message=20?= =?UTF-8?q?with=20deprecated=20flag=20only?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/subspace/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/subspace/main.go b/cmd/subspace/main.go index 06f98128..dbcc7ed1 100644 --- a/cmd/subspace/main.go +++ b/cmd/subspace/main.go @@ -88,7 +88,7 @@ var ( func init() { cli.StringVar(&datadir, "datadir", "/data", "data dir") - cli.StringVar(&backlink, "backlink", "", "[deprecated] Please use `--subdir` for directory path prefix to the subspace instance.") + cli.StringVar(&backlink, "backlink", "", "[deprecated] backlink (optional)") cli.StringVar(&subdir, "subdir", "", "[optional] URL path(without hostname) to subspace instance, without trailing slash") cli.StringVar(&httpHost, "http-host", "", "HTTP host") cli.StringVar(&httpAddr, "http-addr", ":80", "HTTP listen address") From b9ddb0f516da1f4eb19ae629bd1e1de94392a58f Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Sat, 9 Oct 2021 15:40:56 +0800 Subject: [PATCH 29/36] =?UTF-8?q?=F0=9F=A7=A8=20patch:=20typo=20for=20star?= =?UTF-8?q?tup=20delay?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/subspace/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/subspace/main.go b/cmd/subspace/main.go index dbcc7ed1..c6f405ab 100644 --- a/cmd/subspace/main.go +++ b/cmd/subspace/main.go @@ -127,7 +127,7 @@ func main() { subdir = backlink logger.Warnf("You are using a deprecated flag `backlink`, and it will be removed in a future release.\nPlease kindly change the flag to `subdir` to avoid your installation being broken in future updates.") - // sleep for 10 seconds before continue initializing + // sleep for 90 seconds before continue initializing logger.Error("[WARNING] Deprecated flag `backlink` detected, giving a 90 seconds startup delay...") time.Sleep(90 * time.Second) } From ddc8b89c3113daf0177850638980db50cb8e0f8a Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Sat, 9 Oct 2021 15:42:58 +0800 Subject: [PATCH 30/36] =?UTF-8?q?=F0=9F=AA=93=20trim:=20line=20length=20to?= =?UTF-8?q?=20satisfy=20sonarcloud=20standard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Seems we can only do 120 characters max per line... --- cmd/subspace/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/subspace/main.go b/cmd/subspace/main.go index c6f405ab..2b6b4ae8 100644 --- a/cmd/subspace/main.go +++ b/cmd/subspace/main.go @@ -89,7 +89,7 @@ var ( func init() { cli.StringVar(&datadir, "datadir", "/data", "data dir") cli.StringVar(&backlink, "backlink", "", "[deprecated] backlink (optional)") - cli.StringVar(&subdir, "subdir", "", "[optional] URL path(without hostname) to subspace instance, without trailing slash") + cli.StringVar(&subdir, "subdir", "", "[optional] pathname prefix for subspace, without trailing slash") cli.StringVar(&httpHost, "http-host", "", "HTTP host") cli.StringVar(&httpAddr, "http-addr", ":80", "HTTP listen address") cli.BoolVar(&httpInsecure, "http-insecure", false, "enable sessions cookies for http (no https) not recommended") From 27f238ee28feec7fc95a1bfcc21e6bf782963422 Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Sat, 9 Oct 2021 15:44:33 +0800 Subject: [PATCH 31/36] =?UTF-8?q?=F0=9F=AA=93=20trim:=20line=20length=20to?= =?UTF-8?q?=20satisfy=20sonarcloud=20standard,=20again?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/subspace/main.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/subspace/main.go b/cmd/subspace/main.go index 2b6b4ae8..14a2fa0c 100644 --- a/cmd/subspace/main.go +++ b/cmd/subspace/main.go @@ -125,7 +125,8 @@ func main() { // show warning message if deprecated flags are used if backlink != "" { subdir = backlink - logger.Warnf("You are using a deprecated flag `backlink`, and it will be removed in a future release.\nPlease kindly change the flag to `subdir` to avoid your installation being broken in future updates.") + logger.Warnf("You are using a deprecated flag `backlink`, and it will be removed in a future release.") + logger.Warnf("Please change your flag to `subdir` to avoid your breaking your installation in future updates.") // sleep for 90 seconds before continue initializing logger.Error("[WARNING] Deprecated flag `backlink` detected, giving a 90 seconds startup delay...") From eb06d999ccab53465540ba0c65644ab686af7ef9 Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Sat, 9 Oct 2021 16:31:09 +0800 Subject: [PATCH 32/36] =?UTF-8?q?=F0=9F=A7=B9=20revert:=200cb20f857e068379?= =?UTF-8?q?3c67b9d522230d8f9f9f664f?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It seems the httprouter cannot handle index path without trailing slash --- cmd/subspace/handlers.go | 4 ---- cmd/subspace/main.go | 1 - 2 files changed, 5 deletions(-) diff --git a/cmd/subspace/handlers.go b/cmd/subspace/handlers.go index beb1218c..2d5484a4 100644 --- a/cmd/subspace/handlers.go +++ b/cmd/subspace/handlers.go @@ -581,10 +581,6 @@ func profileDeleteHandler(w *Web) { } func indexHandler(w *Web) { - w.Redirect(subdir) -} - -func rootIndexHandler(w *Web) { if w.User.ID != "" { w.TargetProfiles = config.ListProfilesByUser(w.User.ID) } diff --git a/cmd/subspace/main.go b/cmd/subspace/main.go index 14a2fa0c..b49904fc 100644 --- a/cmd/subspace/main.go +++ b/cmd/subspace/main.go @@ -182,7 +182,6 @@ func main() { // r := &httprouter.Router{} - r.GET(subdir, Log(WebHandler(rootIndexHandler, "index"))) r.GET(subdir + "/", Log(WebHandler(indexHandler, "index"))) r.GET(subdir + "/help", Log(WebHandler(helpHandler, "help"))) r.GET(subdir + "/configure", Log(WebHandler(configureHandler, "configure"))) From 7f2f498267a444b653708bf051f1d1552467c97d Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Sat, 9 Oct 2021 17:07:56 +0800 Subject: [PATCH 33/36] =?UTF-8?q?=F0=9F=92=A1=20update:=20golang=20modules?= =?UTF-8?q?=20and=20fix=20go-bindata=20upstream=20path?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/subspace/assets.go | 2 +- go.mod | 21 ++++++++++------ go.sum | 57 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 70 insertions(+), 10 deletions(-) diff --git a/cmd/subspace/assets.go b/cmd/subspace/assets.go index 4ea9fafc..55ddf163 100644 --- a/cmd/subspace/assets.go +++ b/cmd/subspace/assets.go @@ -1,7 +1,7 @@ package main import ( - _ "github.com/jteeuwen/go-bindata" + _ "github.com/kevinburke/go-bindata" ) //go:generate go run github.com/jteeuwen/go-bindata/go-bindata --pkg main static/... templates/... email/... diff --git a/go.mod b/go.mod index 1dcf240e..c5c01dc6 100644 --- a/go.mod +++ b/go.mod @@ -3,18 +3,25 @@ module github.com/subspacecommunity/subspace go 1.14 require ( + github.com/boombuler/barcode v1.0.1 // indirect + github.com/crewjam/httperr v0.2.0 // indirect github.com/crewjam/saml v0.4.5 github.com/dustin/go-humanize v1.0.0 github.com/gorilla/securecookie v1.1.1 - github.com/jteeuwen/go-bindata v3.0.8-0.20180305030458-6025e8de665b+incompatible github.com/julienschmidt/httprouter v1.3.0 + github.com/kevinburke/go-bindata v3.22.0+incompatible + github.com/konsorten/go-windows-terminal-sequences v1.0.3 // indirect + github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect - github.com/pquerna/otp v1.2.0 // indirect - github.com/sirupsen/logrus v1.6.0 - github.com/skip2/go-qrcode v0.0.0-20200519171959-a3b48390827e - golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 - golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476 + github.com/pkg/errors v0.9.1 // indirect + github.com/pquerna/otp v1.3.0 + github.com/russellhaering/goxmldsig v1.1.1 // indirect + github.com/sirupsen/logrus v1.8.1 + github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e + golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 + golang.org/x/net v0.0.0-20211008194852-3b03d305991f + golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac // indirect + golang.org/x/text v0.3.7 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect - gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df ) diff --git a/go.sum b/go.sum index b555c3a6..d5b4cf27 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,16 @@ github.com/beevik/etree v1.0.1 h1:lWzdj5v/Pj1X360EV7bUudox5SRipy4qZLjY0rhb0ck= github.com/beevik/etree v1.0.1/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= -github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI= -github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= +github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI= +github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs= +github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/crewjam/httperr v0.0.0-20190612203328-a946449404da h1:WXnT88cFG2davqSFqvaFfzkSMC0lqh/8/rKZ+z7tYvI= github.com/crewjam/httperr v0.0.0-20190612203328-a946449404da/go.mod h1:+rmNIXRvYMqLQeR4DHyTvs6y0MEMymTz4vyFpFkKTPs= +github.com/crewjam/httperr v0.2.0 h1:b2BfXR8U3AlIHwNeFFvZ+BV1LFvKLlzMjzaTnZMybNo= +github.com/crewjam/httperr v0.2.0/go.mod h1:Jlz+Sg/XqBQhyMjdDiC+GNNRzZTD7x39Gu3pglZ5oH4= github.com/crewjam/saml v0.3.0 h1:nsICCm1susKcMzqhZ+XwOvYUG55Omu1dHlyyknhgh1M= github.com/crewjam/saml v0.3.0/go.mod h1:pzACCdpqjQKTvpPZs5P3FzFNQ+RSOJX5StwHwh7ZUgw= github.com/crewjam/saml v0.4.5 h1:H9u+6CZAESUKHxMyxUbVn0IawYvKZn4nt3d4ccV4O/M= @@ -25,37 +30,62 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22 github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/jonboulle/clockwork v0.2.1 h1:S/EaQvW6FpWMYAvYvY+OBDvpaM+izu0oiwo5y0MH7U0= github.com/jonboulle/clockwork v0.2.1/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= +github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/jteeuwen/go-bindata v3.0.7+incompatible h1:91Uy4d9SYVr1kyTJ15wJsog+esAZZl7JmEfTkwmhJts= +github.com/jteeuwen/go-bindata v3.0.7+incompatible/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= github.com/jteeuwen/go-bindata v3.0.8-0.20180305030458-6025e8de665b+incompatible h1:eX6cWzw+KSwhN430wwbdWPgqnlbnK5ux76/q5ko+Qu8= github.com/jteeuwen/go-bindata v3.0.8-0.20180305030458-6025e8de665b+incompatible/go.mod h1:JVvhzYOiGBnFSYRyV00iY8q7/0PThjIYav1p9h5dmKs= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kevinburke/go-bindata v3.22.0+incompatible h1:/JmqEhIWQ7GRScV0WjX/0tqBrC5D21ALg0H0U/KZ/ts= +github.com/kevinburke/go-bindata v3.22.0+incompatible/go.mod h1:/pEEZ72flUW2p0yi30bslSp9YqD9pysLxunQDdb2CPM= github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mattermost/xml-roundtrip-validator v0.0.0-20201213122252-bcd7e1b9601e h1:qqXczln0qwkVGcpQ+sQuPOVntt2FytYarXXxYSNJkgw= github.com/mattermost/xml-roundtrip-validator v0.0.0-20201213122252-bcd7e1b9601e/go.mod h1:qccnGMcpgwcNaBnxqpJpWWUiPNr5H3O8eDgGV9gT5To= +github.com/mattermost/xml-roundtrip-validator v0.1.0 h1:RXbVD2UAl7A7nOTR4u7E3ILa4IbtvKBHw64LDsmu9hU= +github.com/mattermost/xml-roundtrip-validator v0.1.0/go.mod h1:qccnGMcpgwcNaBnxqpJpWWUiPNr5H3O8eDgGV9gT5To= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pquerna/otp v1.2.0 h1:/A3+Jn+cagqayeR3iHs/L62m5ue7710D35zl1zJ1kok= github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= +github.com/pquerna/otp v1.3.0 h1:oJV/SkzR33anKXwQU3Of42rL4wbrffP4uvUf1SvS5Xs= +github.com/pquerna/otp v1.3.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/russellhaering/goxmldsig v0.0.0-20180430223755-7acd5e4a6ef7 h1:J4AOUcOh/t1XbQcJfkEqhzgvMJ2tDxdCVvmHxW5QXao= github.com/russellhaering/goxmldsig v0.0.0-20180430223755-7acd5e4a6ef7/go.mod h1:Oz4y6ImuOQZxynhbSXk7btjEfNBtGlj2dcaOvXl2FSM= github.com/russellhaering/goxmldsig v1.1.0 h1:lK/zeJie2sqG52ZAlPNn1oBBqsIsEKypUUBGpYYF6lk= github.com/russellhaering/goxmldsig v1.1.0/go.mod h1:QK8GhXPB3+AfuCrfo0oRISa9NfzeCpWmxeGnqEpDF9o= +github.com/russellhaering/goxmldsig v1.1.1 h1:vI0r2osGF1A9PLvsGdPUAGwEIrKa4Pj5sesSBsebIxM= +github.com/russellhaering/goxmldsig v1.1.1/go.mod h1:gM4MDENBQf7M+V824SGfyIUVFWydB7n0KkEubVJl+Tw= github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/skip2/go-qrcode v0.0.0-20200519171959-a3b48390827e h1:xVeSA6fTG0og2KsF+Jh9vzx8gYRtBfLmpXzp3L1eThY= github.com/skip2/go-qrcode v0.0.0-20200519171959-a3b48390827e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= +github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= +github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -69,24 +99,45 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476 h1:E7ct1C6/33eOdrGZKMoyntcEvs2dwZnDe30crG5vpYU= golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20211008194852-3b03d305991f h1:1scJEYZBaF48BaG6tYbtxmLcXqwYGSfGcMoStTqkkIw= +golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac h1:oN6lz7iLW/YC7un8pq+9bOLyXrprv2+DKfkJY+2LJJw= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE= gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -94,3 +145,5 @@ gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 54d7f38c96f7214f0e13516851591a85d60bfddc Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Sat, 9 Oct 2021 17:09:24 +0800 Subject: [PATCH 34/36] =?UTF-8?q?=F0=9F=94=A8=20fix:=20d7af24c8d040d76215b?= =?UTF-8?q?3b1c72cd88c45ee6bb49b?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check and redirect, instead of creating a redirect loop. --- cmd/subspace/web.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/cmd/subspace/web.go b/cmd/subspace/web.go index d8159d8b..9d03c273 100644 --- a/cmd/subspace/web.go +++ b/cmd/subspace/web.go @@ -164,12 +164,13 @@ func WebHandler(h func(*Web), section string) httprouter.Handle { TempTotpKey: tempTotpKey, } - if !config.FindInfo().Configured { - web.Redirect(subdir + "/configure") - return - } - if section == "signin" || section == "forgot" || section == "configure" { + // check if it is authentication stage but instance is not configured + if (section == "signin" || section == "forgot") && !config.FindInfo().Configured { + web.Redirect(subdir + "/configure") + return + } + h(web) return } From 797bc20e26a111fed01d0a4c261051d9d5a64e6b Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Tue, 12 Oct 2021 01:45:52 +0800 Subject: [PATCH 35/36] =?UTF-8?q?=F0=9F=AA=93=20revert=20e01abb139ca772d81?= =?UTF-8?q?1e5e57d7baba36ca507d6d1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index a029c511..5c7aab14 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:alpine as build +FROM golang:1.16-alpine as build RUN apk add --no-cache \ git \ @@ -18,7 +18,7 @@ ENV GODEBUG="netdns=go http2server=0" RUN make build BUILD_VERSION=${BUILD_VERSION} -FROM alpine:latest +FROM alpine:3.13.4 LABEL maintainer="github.com/subspacecommunity/subspace" COPY --from=build /src/subspace /usr/bin/subspace From 9173cc9ea8346eae5fbedcee2741a118c6396a97 Mon Sep 17 00:00:00 2001 From: Ivan Ip Date: Sun, 17 Oct 2021 00:08:23 +0800 Subject: [PATCH 36/36] =?UTF-8?q?=F0=9F=92=88=20patch:=20revert=20and=20pa?= =?UTF-8?q?tch=20entrypoint.sh=20for=20backward=20compatability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- entrypoint.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/entrypoint.sh b/entrypoint.sh index 5a3f2211..fbcfb9c9 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -9,6 +9,12 @@ if [ -z "${SUBSPACE_HTTP_HOST-}" ]; then echo "Environment variable SUBSPACE_HTTP_HOST required. Exiting." exit 1 fi + +# Configuring depreacted flags for backward compatibility +if [ -z "${SUBSPACE_BACKLINK-}" ]; then + export SUBSPACE_BACKLINK="/" +fi + # Optional environment variables. if [ -z "${SUBSPACE_URL_SUBDIRECTORY-}" ]; then export SUBSPACE_URL_SUBDIRECTORY="" @@ -240,6 +246,7 @@ exec /usr/bin/subspace \ "--http-host=${SUBSPACE_HTTP_HOST}" \ "--http-addr=${SUBSPACE_HTTP_ADDR}" \ "--http-insecure=${SUBSPACE_HTTP_INSECURE}" \ + "--backlink=${SUBSPACE_BACKLINK}" \ "--subdir=${SUBSPACE_URL_SUBDIRECTORY}" \ "--letsencrypt=${SUBSPACE_LETSENCRYPT}" \ "--theme=${SUBSPACE_THEME}"