Weighs the soul of incoming HTTP requests to stop AI crawlers

feat(localization): Add option for forcing a language (#742)

* Add forcesLanguage option

* Change comments for forced language option

* Add changes to CHANGELOG.md

---------

Signed-off-by: Xe Iaso <me@xeiaso.net>
Co-authored-by: Xe Iaso <me@xeiaso.net>

authored by

Martin
Xe Iaso
and committed by
GitHub
0e431383 c981c23f

+19 -7
+4
anubis.go
··· 32 32 // DefaultDifficulty is the default "difficulty" (number of leading zeroes) 33 33 // that must be met by the client in order to pass the challenge. 34 34 const DefaultDifficulty = 4 35 + 36 + // ForcedLanguage is the language being used instead of the one of the request's Accept-Language header 37 + // if being set. 38 + var ForcedLanguage = ""
+2
cmd/anubis/main.go
··· 50 50 cookieExpiration = flag.Duration("cookie-expiration-time", anubis.CookieDefaultExpirationTime, "The amount of time the authorization cookie is valid for") 51 51 cookiePrefix = flag.String("cookie-prefix", "techaro.lol-anubis", "prefix for browser cookies created by Anubis") 52 52 cookiePartitioned = flag.Bool("cookie-partitioned", false, "if true, sets the partitioned flag on Anubis cookies, enabling CHIPS support") 53 + forcedLanguage = flag.String("forced-language", "", "if set, this language is being used instead of the one from the request's Accept-Language header") 53 54 hs512Secret = flag.String("hs512-secret", "", "secret used to sign JWTs, uses ed25519 if not set") 54 55 cookieSecure = flag.Bool("cookie-secure", true, "if true, sets the secure flag on Anubis cookies") 55 56 ed25519PrivateKeyHex = flag.String("ed25519-private-key-hex", "", "private key used to sign JWTs, if not set a random one will be assigned") ··· 378 379 379 380 anubis.CookieName = *cookiePrefix + "-auth" 380 381 anubis.TestCookieName = *cookiePrefix + "-cookie-verification" 382 + anubis.ForcedLanguage = *forcedLanguage 381 383 382 384 // If OpenGraph configuration values are not set in the config file, use the 383 385 // values from flags / envvars.
+3 -3
docs/docs/CHANGELOG.md
··· 13 13 <!-- This changes the project to: --> 14 14 - Add `COOKIE_SECURE` option to set the cookie [Secure flag](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Cookies#block_access_to_your_cookies) 15 15 - Sets cookie defaults to use [SameSite: None](https://web.dev/articles/samesite-cookies-explained) 16 - 17 16 - Determine the `BIND_NETWORK`/`--bind-network` value from the bind address ([#677](https://github.com/TecharoHQ/anubis/issues/677)). 18 17 - Implement localization system. Find locale files in lib/localization/locales/. 19 18 - Implement a [development container](https://containers.dev/) manifest to make contributions easier. 20 - - Fix dynamic cookie domains functionality ([#731](https://github.com/TecharoHQ/anubis/pull/731)). 21 - - Add option for custom cookie prefix ([#732](https://github.com/TecharoHQ/anubis/pull/732)). 19 + - Fix dynamic cookie domains functionality ([#731](https://github.com/TecharoHQ/anubis/pull/731)) 20 + - Add option for custom cookie prefix ([#732](https://github.com/TecharoHQ/anubis/pull/732)) 22 21 - Remove the "Success" interstitial after a proof of work challenge is concluded. 22 + - Add option for forcing a specific language ([#742](https://github.com/TecharoHQ/anubis/pull/742)) 23 23 24 24 ## v1.20.0: Thancred Waters 25 25
+10 -4
lib/localization/localization.go
··· 3 3 import ( 4 4 "embed" 5 5 "encoding/json" 6 + "github.com/TecharoHQ/anubis" 6 7 "net/http" 7 8 "strings" 8 9 "sync" ··· 57 58 58 59 globalService = &LocalizationService{bundle: bundle} 59 60 }) 60 - 61 + 61 62 // Safety check - if globalService is still nil, create a minimal one 62 63 if globalService == nil { 63 64 bundle := i18n.NewBundle(language.English) 64 65 bundle.RegisterUnmarshalFunc("json", json.Unmarshal) 65 66 globalService = &LocalizationService{bundle: bundle} 66 67 } 67 - 68 + 68 69 return globalService 69 70 } 70 71 ··· 93 94 return sl.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: messageID}) 94 95 } 95 96 96 - // GetLocalizer creates a localizer based on the request's Accept-Language header 97 + // GetLocalizer creates a localizer based on the request's Accept-Language header or forcedLanguage option 97 98 func GetLocalizer(r *http.Request) *SimpleLocalizer { 98 - localizer := NewLocalizationService().GetLocalizerFromRequest(r) 99 + var localizer *i18n.Localizer 100 + if anubis.ForcedLanguage == "" { 101 + localizer = NewLocalizationService().GetLocalizerFromRequest(r) 102 + } else { 103 + localizer = NewLocalizationService().GetLocalizer(anubis.ForcedLanguage) 104 + } 99 105 return &SimpleLocalizer{Localizer: localizer} 100 106 }