fix(api): normalise authentik public paths

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-02 13:38:56 +00:00
parent f234fcba5f
commit f6add24177
3 changed files with 46 additions and 2 deletions

View file

@ -235,7 +235,39 @@ func authentikMiddleware(cfg AuthentikConfig, publicPaths func() []string) gin.H
func cloneAuthentikConfig(cfg AuthentikConfig) AuthentikConfig {
out := cfg
out.PublicPaths = slices.Clone(cfg.PublicPaths)
out.PublicPaths = normalisePublicPaths(cfg.PublicPaths)
return out
}
// normalisePublicPaths trims whitespace, ensures a leading slash, and removes
// duplicate entries while preserving the first occurrence of each path.
func normalisePublicPaths(paths []string) []string {
if len(paths) == 0 {
return nil
}
out := make([]string, 0, len(paths))
seen := make(map[string]struct{}, len(paths))
for _, path := range paths {
path = strings.TrimSpace(path)
if path == "" {
continue
}
if !strings.HasPrefix(path, "/") {
path = "/" + path
}
path = strings.TrimRight(path, "/")
if path == "" {
path = "/"
}
if _, ok := seen[path]; ok {
continue
}
seen[path] = struct{}{}
out = append(out, path)
}
return out
}

View file

@ -219,6 +219,18 @@ func TestEngine_AuthentikConfig_Good_ClonesPublicPaths(t *testing.T) {
}
}
func TestEngine_AuthentikConfig_Good_NormalisesPublicPaths(t *testing.T) {
e, _ := api.New(api.WithAuthentik(api.AuthentikConfig{
PublicPaths: []string{" /public/ ", "docs", "/public"},
}))
cfg := e.AuthentikConfig()
expected := []string{"/public", "/docs"}
if !slices.Equal(cfg.PublicPaths, expected) {
t.Fatalf("expected normalised public paths %v, got %v", expected, cfg.PublicPaths)
}
}
func TestEngine_Register_Good_IgnoresNilGroups(t *testing.T) {
e, _ := api.New()

View file

@ -42,7 +42,7 @@ func TestEngine_Good_OpenAPISpecBuilderCarriesEngineMetadata(t *testing.T) {
Issuer: "https://auth.example.com",
ClientID: "core-client",
TrustedProxy: true,
PublicPaths: []string{"/public", "/docs"},
PublicPaths: []string{" /public/ ", "docs", "/public"},
}),
api.WithWSPath("/socket"),
api.WithWSHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})),