feat(server): add ExtAuth logout URL configuration (#5074)
* feat(server): add ExtAuth logout URL configuration (#4467) When external authentication (reverse proxy auth) is active, the Logout button is hidden because authentication is managed externally. Many external auth services (Authelia, Authentik, Keycloak) provide a logout URL that can terminate the session. Add `ExtAuth.LogoutURL` config option that, when set, shows the Logout button in the UI and redirects the user to the external auth provider's logout endpoint instead of the Navidrome login page. * feat(server): add validation for ExtAuth logout URL configuration * feat(server): refactor ExtAuth logout URL validation to a reusable function * fix(configuration): rename URL validation functions for consistency Signed-off-by: Deluan <deluan@navidrome.org> * fix(configuration): rename URL validation functions for consistency Signed-off-by: Deluan <deluan@navidrome.org> --------- Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
@@ -52,6 +52,48 @@ var _ = Describe("Configuration", func() {
|
||||
})
|
||||
})
|
||||
|
||||
Describe("ValidateURL", func() {
|
||||
It("accepts a valid http URL", func() {
|
||||
fn := conf.ValidateURL("TestOption", "http://example.com/path")
|
||||
Expect(fn()).To(Succeed())
|
||||
})
|
||||
|
||||
It("accepts a valid https URL", func() {
|
||||
fn := conf.ValidateURL("TestOption", "https://example.com/path")
|
||||
Expect(fn()).To(Succeed())
|
||||
})
|
||||
|
||||
It("rejects a URL with no scheme", func() {
|
||||
fn := conf.ValidateURL("TestOption", "example.com/path")
|
||||
Expect(fn()).To(MatchError(ContainSubstring("invalid scheme")))
|
||||
})
|
||||
|
||||
It("rejects a URL with an unsupported scheme", func() {
|
||||
fn := conf.ValidateURL("TestOption", "javascript://example.com/path")
|
||||
Expect(fn()).To(MatchError(ContainSubstring("invalid scheme")))
|
||||
})
|
||||
|
||||
It("accepts an empty URL (optional config)", func() {
|
||||
fn := conf.ValidateURL("TestOption", "")
|
||||
Expect(fn()).To(Succeed())
|
||||
})
|
||||
|
||||
It("includes the option name in the error message", func() {
|
||||
fn := conf.ValidateURL("MyOption", "ftp://example.com")
|
||||
Expect(fn()).To(MatchError(ContainSubstring("MyOption")))
|
||||
})
|
||||
|
||||
It("rejects a URL that cannot be parsed", func() {
|
||||
fn := conf.ValidateURL("TestOption", "://invalid")
|
||||
Expect(fn()).To(HaveOccurred())
|
||||
})
|
||||
|
||||
It("rejects a URL without a host", func() {
|
||||
fn := conf.ValidateURL("TestOption", "http:///path")
|
||||
Expect(fn()).To(MatchError(ContainSubstring("non-empty host is required")))
|
||||
})
|
||||
})
|
||||
|
||||
DescribeTable("NormalizeSearchBackend",
|
||||
func(input, expected string) {
|
||||
Expect(conf.NormalizeSearchBackend(input)).To(Equal(expected))
|
||||
|
||||
Reference in New Issue
Block a user