diff --git a/README.md b/README.md index d59616d0..ccb92e93 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 | +| `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 page to set the home button to | +| `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/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/cmd/subspace/handlers.go b/cmd/subspace/handlers.go index 229417be..2d5484a4 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, "/", 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("/?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("/configure?error=invalid") + w.Redirect(subdir + "/configure?error=invalid") return } hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { - w.Redirect("/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("/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("/forgot?error=invalid") + w.Redirect(subdir + "/forgot?error=invalid") return } if secret != "" && !validString.MatchString(secret) { - w.Redirect("/forgot?error=invalid") + w.Redirect(subdir + "/forgot?error=invalid") return } if email != "" && secret != "" && !validPassword.MatchString(password) { - w.Redirect("/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("/forgot?error=invalid") + w.Redirect(subdir + "/forgot?error=invalid") return } @@ -203,18 +203,18 @@ func forgotHandler(w *Web) { } }() - w.Redirect("/forgot?success=forgot") + w.Redirect(subdir + "/forgot?success=forgot") return } if secret != config.FindInfo().Secret { - w.Redirect("/forgot?error=invalid") + w.Redirect(subdir + "/forgot?error=invalid") return } hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { - w.Redirect("/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("/") + w.Redirect(subdir) } func signoutHandler(w *Web) { w.SignoutSession() - w.Redirect("/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("/signin?error=invalid") + w.Redirect(subdir + "/signin?error=invalid") return } if err := bcrypt.CompareHashAndPassword(config.FindInfo().Password, []byte(password)); err != nil { - w.Redirect("/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("/signin?error=invalid") + w.Redirect(subdir + "/signin?error=invalid") return } @@ -266,7 +266,7 @@ func signinHandler(w *Web) { return } - w.Redirect("/") + 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("/") + w.Redirect(subdir + "/") return } @@ -322,7 +322,7 @@ func userEditHandler(w *Web) { } if w.User.ID == user.ID { - w.Redirect("/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("/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("/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("/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("/?success=deleteuser") + w.Redirect(subdir + "?success=deleteuser") } func profileAddHandler(w *Web) { @@ -391,7 +391,7 @@ func profileAddHandler(w *Web) { } if name == "" { - w.Redirect("/?error=profilename") + w.Redirect(subdir + "?error=profilename") return } @@ -403,14 +403,14 @@ func profileAddHandler(w *Web) { } if len(config.ListProfiles()) >= maxProfiles { - w.Redirect("/?error=addprofile") + w.Redirect(subdir + "?error=addprofile") return } profile, err := config.AddProfile(userID, name, platform) if err != nil { logger.Warn(err) - w.Redirect("/?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("/?error=addprofile") + w.Redirect(subdir + "?error=addprofile") return } - w.Redirect("/profile/connect/%s?success=addprofile", profile.ID) + w.Redirect(subdir + "/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(subdir + "/profile/delete?error=deleteprofile") return } - if w.Admin { - w.Redirect("/user/edit/%s?success=deleteprofile", profile.UserID) + if len(profile.UserID) > 0 && w.Admin { + w.Redirect(subdir + "/user/edit/%s?success=deleteprofile", profile.UserID) return } - w.Redirect("/?success=deleteprofile") + w.Redirect(subdir + "?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(subdir + "/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(subdir + "/settings?error=invalid") return } if err := bcrypt.CompareHashAndPassword(config.FindInfo().Password, []byte(currentPassword)); err != nil { - w.Redirect("/settings?error=invalid") + w.Redirect(subdir + "/settings?error=invalid") return } hashedPassword, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost) if err != nil { - w.Redirect("/settings?error=bcrypt") + w.Redirect(subdir + "/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(subdir + "/settings?error=totp") return } - w.Redirect("/settings?success=totp") + w.Redirect(subdir + "/settings?success=totp") return } if config.Info.TotpKey == "" && totpCode != "" { if !totp.Validate(totpCode, tempTotpKey.Secret()) { - w.Redirect("/settings?error=totp") + w.Redirect(subdir + "/settings?error=totp") return } config.Info.TotpKey = tempTotpKey.Secret() config.save() } - w.Redirect("/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 1956ac9d..b49904fc 100644 --- a/cmd/subspace/main.go +++ b/cmd/subspace/main.go @@ -45,7 +45,8 @@ var ( // Insecure http cookies (only recommended for internal LANs/VPNs) httpInsecure bool - // backlink + // subdir + subdir string backlink string // show version @@ -87,7 +88,8 @@ var ( func init() { cli.StringVar(&datadir, "datadir", "/data", "data dir") - cli.StringVar(&backlink, "backlink", "/", "backlink (optional)") + cli.StringVar(&backlink, "backlink", "", "[deprecated] backlink (optional)") + 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") @@ -120,6 +122,17 @@ 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.") + 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...") + time.Sleep(90 * time.Second) + } + // http host if httpHost == "" { usage("--http-host flag is required") @@ -168,41 +181,42 @@ 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(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("/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(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 @@ -224,10 +238,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: subdir, }) logger.Fatal(httpd.ListenAndServe()) } @@ -253,7 +270,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(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) @@ -315,10 +332,13 @@ 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, - Path: "/", + Path: subdir, }) logger.Fatal(httpsd.Serve(tlsListener)) } @@ -377,7 +397,7 @@ func configureSAML() error { rootURL := url.URL{ Scheme: "https", Host: httpHost, - Path: "/", + Path: subdir, } if httpInsecure { diff --git a/cmd/subspace/web.go b/cmd/subspace/web.go index 81c55686..9d03c273 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,12 +165,13 @@ func WebHandler(h func(*Web), section string) httprouter.Handle { } if section == "signin" || section == "forgot" || section == "configure" { - h(web) - return - } + // check if it is authentication stage but instance is not configured + if (section == "signin" || section == "forgot") && !config.FindInfo().Configured { + web.Redirect(subdir + "/configure") + return + } - if !config.FindInfo().Configured { - web.Redirect("/configure") + h(web) return } @@ -243,7 +244,7 @@ func WebHandler(h func(*Web), section string) httprouter.Handle { } logger.Warnf("auth: sign in required") - web.Redirect("/signin") + web.Redirect(subdir + "/signin") } } @@ -304,7 +305,7 @@ func (w *Web) SignoutSession() { http.SetCookie(w.w, &http.Cookie{ Name: SessionCookieNameSSO, Value: "", - Path: "/", + Path: subdir, HttpOnly: true, Domain: httpHost, Secure: !httpInsecure, @@ -315,7 +316,7 @@ func (w *Web) SignoutSession() { http.SetCookie(w.w, &http.Cookie{ Name: SessionCookieName, Value: "", - Path: "/", + Path: subdir, HttpOnly: true, Domain: httpHost, Secure: !httpInsecure, @@ -339,7 +340,7 @@ func (w *Web) SigninSession(admin bool, userID string) error { http.SetCookie(w.w, &http.Cookie{ Name: SessionCookieName, Value: encoded, - Path: "/", + Path: subdir, HttpOnly: true, Domain: httpHost, Secure: !httpInsecure, diff --git a/entrypoint.sh b/entrypoint.sh index 9b1814b2..fbcfb9c9 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -9,11 +9,17 @@ if [ -z "${SUBSPACE_HTTP_HOST-}" ]; then echo "Environment variable SUBSPACE_HTTP_HOST required. Exiting." exit 1 fi -# Optional environment variables. + +# 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="" +fi + if [ -z "${SUBSPACE_IPV4_POOL-}" ]; then export SUBSPACE_IPV4_POOL="10.99.97.0/24" fi @@ -46,14 +52,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 @@ -236,6 +247,7 @@ exec /usr/bin/subspace \ "--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/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= diff --git a/web/templates/configure.html b/web/templates/configure.html index 7ea4ed4c..fad8a9d7 100644 --- a/web/templates/configure.html +++ b/web/templates/configure.html @@ -34,7 +34,7 @@
-