aboutsummaryrefslogtreecommitdiff
path: root/lib/anubis.go
diff options
context:
space:
mode:
authorJason Cameron <git@jasoncameron.dev>2025-04-25 14:39:38 -0400
committerGitHub <noreply@github.com>2025-04-25 14:39:38 -0400
commit24f8ba729b180fb420995b8c6b592f23b3e5a552 (patch)
treeb9ee24e053fac2125a74bd1d92818a0f7922a94d /lib/anubis.go
parent6858f66a62416354a349d8090fcb45b5262056eb (diff)
downloadanubis-24f8ba729b180fb420995b8c6b592f23b3e5a552.tar.xz
anubis-24f8ba729b180fb420995b8c6b592f23b3e5a552.zip
feat: add support for a base prefix (#294)
* fix: rename variable for preventing collision in ED25519 private key handling Signed-off-by: Jason Cameron <git@jasoncameron.dev> * fix: remove unused import and debug print in xess.go Signed-off-by: Jason Cameron <git@jasoncameron.dev> * feat: introduce base path configuration for Anubis endpoints Closes: #231 Signed-off-by: Jason Cameron <git@jasoncameron.dev> * hack(internal/test): skip these tests for now Signed-off-by: Xe Iaso <me@xeiaso.net> * fix(yeet): unbreak package builds Signed-off-by: Xe Iaso <me@xeiaso.net> --------- Signed-off-by: Jason Cameron <git@jasoncameron.dev> Signed-off-by: Xe Iaso <me@xeiaso.net> Co-authored-by: Xe Iaso <me@xeiaso.net>
Diffstat (limited to 'lib/anubis.go')
-rw-r--r--lib/anubis.go54
1 files changed, 39 insertions, 15 deletions
diff --git a/lib/anubis.go b/lib/anubis.go
index 8ca6964..70eb37e 100644
--- a/lib/anubis.go
+++ b/lib/anubis.go
@@ -80,6 +80,7 @@ type Options struct {
Target string
WebmasterEmail string
+ BasePrefix string
}
func LoadPoliciesOrDefault(fname string, defaultDifficulty int) (*policy.ParsedConfig, error) {
@@ -121,6 +122,8 @@ func New(opts Options) (*Server, error) {
opts.PrivateKey = priv
}
+ anubis.BasePrefix = opts.BasePrefix
+
result := &Server{
next: opts.Next,
priv: opts.PrivateKey,
@@ -134,26 +137,42 @@ func New(opts Options) (*Server, error) {
mux := http.NewServeMux()
xess.Mount(mux)
- mux.Handle(anubis.StaticPath, internal.UnchangingCache(internal.NoBrowsing(http.StripPrefix(anubis.StaticPath, http.FileServerFS(web.Static)))))
+ // Helper to add global prefix
+ registerWithPrefix := func(pattern string, handler http.Handler, method string) {
+ if method != "" {
+ method = method + " " // methods must end with a space to register with them
+ }
- if opts.ServeRobotsTXT {
- mux.HandleFunc("/robots.txt", func(w http.ResponseWriter, r *http.Request) {
- http.ServeFileFS(w, r, web.Static, "static/robots.txt")
- })
+ // Ensure there's no double slash when concatenating BasePrefix and pattern
+ basePrefix := strings.TrimSuffix(anubis.BasePrefix, "/")
+ prefix := method + basePrefix
- mux.HandleFunc("/.well-known/robots.txt", func(w http.ResponseWriter, r *http.Request) {
- http.ServeFileFS(w, r, web.Static, "static/robots.txt")
- })
+ // If pattern doesn't start with a slash, add one
+ if !strings.HasPrefix(pattern, "/") {
+ pattern = "/" + pattern
+ }
+
+ mux.Handle(prefix+pattern, handler)
}
- // mux.HandleFunc("GET /.within.website/x/cmd/anubis/static/js/main.mjs", serveMainJSWithBestEncoding)
+ // Ensure there's no double slash when concatenating BasePrefix and StaticPath
+ stripPrefix := strings.TrimSuffix(anubis.BasePrefix, "/") + anubis.StaticPath
+ registerWithPrefix(anubis.StaticPath, internal.UnchangingCache(internal.NoBrowsing(http.StripPrefix(stripPrefix, http.FileServerFS(web.Static)))), "")
- mux.HandleFunc("POST /.within.website/x/cmd/anubis/api/make-challenge", result.MakeChallenge)
- mux.HandleFunc("GET /.within.website/x/cmd/anubis/api/pass-challenge", result.PassChallenge)
- mux.HandleFunc("GET /.within.website/x/cmd/anubis/api/check", result.maybeReverseProxyHttpStatusOnly)
- mux.HandleFunc("GET /.within.website/x/cmd/anubis/api/test-error", result.TestError)
+ if opts.ServeRobotsTXT {
+ registerWithPrefix("/robots.txt", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ http.ServeFileFS(w, r, web.Static, "static/robots.txt")
+ }), "GET")
+ registerWithPrefix("/.well-known/robots.txt", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ http.ServeFileFS(w, r, web.Static, "static/robots.txt")
+ }), "GET")
+ }
- mux.HandleFunc("/", result.maybeReverseProxyOrPage)
+ registerWithPrefix(anubis.APIPrefix+"make-challenge", http.HandlerFunc(result.MakeChallenge), "POST")
+ registerWithPrefix(anubis.APIPrefix+"pass-challenge", http.HandlerFunc(result.PassChallenge), "GET")
+ registerWithPrefix(anubis.APIPrefix+"check", http.HandlerFunc(result.maybeReverseProxyHttpStatusOnly), "")
+ registerWithPrefix(anubis.APIPrefix+"test-error", http.HandlerFunc(result.TestError), "GET")
+ registerWithPrefix("/", http.HandlerFunc(result.maybeReverseProxyOrPage), "")
result.mux = mux
@@ -561,6 +580,11 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) {
return
}
+ // Adjust cookie path if base prefix is not empty
+ cookiePath := "/"
+ if anubis.BasePrefix != "" {
+ cookiePath = strings.TrimSuffix(anubis.BasePrefix, "/") + "/"
+ }
// generate JWT cookie
token := jwt.NewWithClaims(jwt.SigningMethodEdDSA, jwt.MapClaims{
"challenge": challenge,
@@ -585,7 +609,7 @@ func (s *Server) PassChallenge(w http.ResponseWriter, r *http.Request) {
SameSite: http.SameSiteLaxMode,
Domain: s.opts.CookieDomain,
Partitioned: s.opts.CookiePartitioned,
- Path: "/",
+ Path: cookiePath,
})
challengesValidated.Inc()