fix: single source of truth for local-login lockout rescue

HandleLocalLogin and HandleListPublicProviders each computed their own
answer to whether password sign-in must stay available, and they could
disagree: an instance with local login off and a licence that lapses
loses its only provider and its password form in the same moment, with
no endpoint left to recover. services.LocalLoginPermitted is now the
one predicate both call.
This commit is contained in:
2026-08-03 14:11:22 +01:00
parent fa7c5d341d
commit c03360333b
2 changed files with 27 additions and 8 deletions
+2 -8
View File
@@ -67,7 +67,7 @@ func HandleLocalLogin(c *gin.Context) {
}
// The login page hides the form, but the page is a courtesy and the API is
// the boundary.
if !services.IsLocalLoginEnabled(instanceID) {
if !services.LocalLoginPermitted(instanceID) {
c.JSON(http.StatusForbidden, gin.H{"error": "password sign-in is disabled for this instance"})
return
}
@@ -118,13 +118,7 @@ func HandleListPublicProviders(c *gin.Context) {
}
}
localEnabled := services.IsLocalLoginEnabled(instanceID)
// Belt and braces against a hand-edited database: a login page with neither
// a form nor a button is unrecoverable without database access.
if !localEnabled && len(out) == 0 {
localEnabled = true
}
c.JSON(http.StatusOK, gin.H{"local_enabled": localEnabled, "providers": out})
c.JSON(http.StatusOK, gin.H{"local_enabled": services.LocalLoginPermitted(instanceID), "providers": out})
}
func HandleBootstrapStatus(c *gin.Context) {