diff --git a/docs/docs/CHANGELOG.md b/docs/docs/CHANGELOG.md index 050b55b..43e2196 100644 --- a/docs/docs/CHANGELOG.md +++ b/docs/docs/CHANGELOG.md @@ -99,6 +99,9 @@ There are a bunch of other assorted features and fixes too: - Allow [Common Crawl](https://commoncrawl.org/) by default so scrapers have less incentive to scrape - The [bbolt storage backend](./admin/policies.mdx#bbolt) now runs its cleanup every hour instead of every five minutes. - Don't block Anubis starting up if [Thoth](./admin/thoth.mdx) health checks fail. +- A race condition involving [opening two challenge pages at once in different tabs](https://github.com/TecharoHQ/anubis/issues/832) causing one of them to fail has been fixed. +- The "Try again" button on the error page has been fixed. Previously it meant "try the solution again" instead of "try the challenge again". +- In certain cases, a user could be stuck with a test cookie that is invalid, locking them out of the service for up to half an hour. This has been fixed with better validation of this case and clearing the cookie. ### Potentially breaking changes diff --git a/lib/anubis.go b/lib/anubis.go index a3b9338..e9435f9 100644 --- a/lib/anubis.go +++ b/lib/anubis.go @@ -394,8 +394,6 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) { return } - s.ClearCookie(w, CookieOpts{Name: anubis.TestCookieName, Host: r.Host}) - redir := r.FormValue("redir") redirURL, err := url.ParseRequestURI(redir) if err != nil { diff --git a/lib/http.go b/lib/http.go index 7c59c39..d1e8233 100644 --- a/lib/http.go +++ b/lib/http.go @@ -131,6 +131,7 @@ func (s *Server) RenderIndex(w http.ResponseWriter, r *http.Request, rule *polic chall, err := s.challengeFor(r) if err != nil { lg.Error("can't get challenge", "err", "err") + s.ClearCookie(w, CookieOpts{Name: anubis.TestCookieName, Host: r.Host}) s.respondWithError(w, r, fmt.Sprintf("%s: %s", localizer.T("internal_server_error"), rule.Challenge.Algorithm)) return } @@ -155,6 +156,7 @@ func (s *Server) RenderIndex(w http.ResponseWriter, r *http.Request, rule *polic impl, ok := challenge.Get(rule.Challenge.Algorithm) if !ok { lg.Error("check failed", "err", "can't get algorithm", "algorithm", rule.Challenge.Algorithm) + s.ClearCookie(w, CookieOpts{Name: anubis.TestCookieName, Host: r.Host}) s.respondWithError(w, r, fmt.Sprintf("%s: %s", localizer.T("internal_server_error"), rule.Challenge.Algorithm)) return } @@ -196,7 +198,7 @@ func (s *Server) respondWithError(w http.ResponseWriter, r *http.Request, messag func (s *Server) respondWithStatus(w http.ResponseWriter, r *http.Request, msg string, status int) { localizer := localization.GetLocalizer(r) - templ.Handler(web.Base(localizer.T("oh_noes"), web.ErrorPage(msg, s.opts.WebmasterEmail, localizer), s.policy.Impressum, localizer), templ.WithStatus(status)).ServeHTTP(w, r) + templ.Handler(web.Base(localizer.T("oh_noes"), web.ErrorPage(msg, s.opts.WebmasterEmail, r.FormValue("redir"), localizer), s.policy.Impressum, localizer), templ.WithStatus(status)).ServeHTTP(w, r) } func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { diff --git a/web/index.go b/web/index.go index 90bf98f..ef58d4a 100644 --- a/web/index.go +++ b/web/index.go @@ -25,8 +25,8 @@ func Index(localizer *localization.SimpleLocalizer) templ.Component { return index(localizer) } -func ErrorPage(msg string, mail string, localizer *localization.SimpleLocalizer) templ.Component { - return errorPage(msg, mail, localizer) +func ErrorPage(msg, mail, redirect string, localizer *localization.SimpleLocalizer) templ.Component { + return errorPage(msg, mail, redirect, localizer) } func Bench(localizer *localization.SimpleLocalizer) templ.Component { diff --git a/web/index.templ b/web/index.templ index e8094e0..d755b83 100644 --- a/web/index.templ +++ b/web/index.templ @@ -10,7 +10,7 @@ import ( templ base(title string, body templ.Component, impressum *config.Impressum, challenge any, ogTags map[string]string, localizer *localization.SimpleLocalizer) { - +
{ message }.
- + if mail != "" {{ localizer.T("go_home") } { localizer.T("contact_webmaster") } diff --git a/web/index_templ.go b/web/index_templ.go index 921ba52..d83cbe5 100644 --- a/web/index_templ.go +++ b/web/index_templ.go @@ -44,7 +44,7 @@ func base(title string, body templ.Component, impressum *config.Impressum, chall var templ_7745c5c3_Var2 string templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.GetLang()) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 13, Col: 32} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 13, Col: 33} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) if templ_7745c5c3_Err != nil { @@ -427,7 +427,20 @@ func index(localizer *localization.SimpleLocalizer) templ.Component { }) } -func errorPage(message string, mail string, localizer *localization.SimpleLocalizer) templ.Component { +func reload(redirect string) templ.ComponentScript { + return templ.ComponentScript{ + Name: `__templ_reload_f48f`, + Function: `function __templ_reload_f48f(redirect){if (redirect === "") { + redirect = "/"; + } + window.location = redirect; +}`, + Call: templ.SafeScript(`__templ_reload_f48f`, redirect), + CallInline: templ.SafeScriptInline(`__templ_reload_f48f`, redirect), + } +} + +func errorPage(message, mail, redirect string, localizer *localization.SimpleLocalizer) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { @@ -455,7 +468,7 @@ func errorPage(message string, mail string, localizer *localization.SimpleLocali var templ_7745c5c3_Var27 string templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/img/reject.webp?cacheBuster=" + anubis.Version) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 127, Col: 181} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 134, Col: 181} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27)) if templ_7745c5c3_Err != nil { @@ -468,95 +481,94 @@ func errorPage(message string, mail string, localizer *localization.SimpleLocali var templ_7745c5c3_Var28 string templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(message) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 128, Col: 14} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 135, Col: 14} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, ".
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if mail != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var30 string - templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("go_home")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 132, Col: 40} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var31 string - templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("contact_webmaster")) + templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("go_home")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 132, Col: 81} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 139, Col: 40} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var32 templ.SafeURL - templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinURLErrs("mailto:" + templ.SafeURL(mail)) + var templ_7745c5c3_Var32 string + templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("contact_webmaster")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 133, Col: 45} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 139, Col: 81} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "\">") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var38 string + templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("static_check_endpoint")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 158, Col: 43} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var39 string - templ_7745c5c3_Var39, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("time")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 162, Col: 51} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var39)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, " | ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var45 string
- templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.JoinStringErrs(anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/img/pensive.webp?cacheBuster=" + anubis.Version)
+ templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.JoinStringErrs(localizer.T("iters_b"))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 178, Col: 166}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 176, Col: 52}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var45))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "\"> | ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, " |
---|