feat: Enhance login functionality to support external authentication providers

- Updated the Login template to conditionally display external authentication options based on the presence of enabled providers.
- Modified the HandleLoginPage and HandleLogin functions to check for available external providers and pass this information to the Login template.
- Improved user experience by dynamically showing or hiding external sign-in options during the login process.
This commit is contained in:
StarFleetCPTN
2025-04-07 09:24:46 -07:00
parent d691fc837e
commit 3654161245
2 changed files with 34 additions and 15 deletions
+10 -8
View File
@@ -5,7 +5,7 @@ import (
"strings"
)
templ Login(ctx context.Context, errorMessage string) {
templ Login(ctx context.Context, errorMessage string, hasExternalProviders bool) {
@LayoutWithContext("Login", ctx) {
<div class="min-h-[calc(100vh-4rem)] flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8 bg-gray-50 dark:bg-gray-900">
<div class="max-w-md w-full space-y-8">
@@ -116,15 +116,17 @@ templ Login(ctx context.Context, errorMessage string) {
Contact an administrator to create an account
</p>
<!-- External Authentication Providers -->
<div id="external-auth-providers" class="mt-4">
<p class="text-sm text-gray-600 dark:text-gray-300 mb-3">Or sign in with:</p>
<div id="provider-buttons" class="flex flex-col gap-2" hx-get="/auth/providers" hx-trigger="load" hx-target="#provider-buttons">
<div class="animate-pulse flex justify-center">
<div class="h-10 bg-gray-200 rounded w-full max-w-[200px] dark:bg-gray-700"></div>
if hasExternalProviders {
<!-- External Authentication Providers -->
<div id="external-auth-providers" class="mt-4">
<p class="text-sm text-gray-600 dark:text-gray-300 mb-3">Or sign in with:</p>
<div id="provider-buttons" class="flex flex-col gap-2" hx-get="/auth/providers" hx-trigger="load" hx-target="#provider-buttons">
<div class="animate-pulse flex justify-center">
<div class="h-10 bg-gray-200 rounded w-full max-w-[200px] dark:bg-gray-700"></div>
</div>
</div>
</div>
</div>
}
</div>
</div>
+24 -7
View File
@@ -278,11 +278,20 @@ func (h *Handlers) HandleLoginPage(c *gin.Context) {
// Check for message query param (used for password expired, etc.)
message := c.Query("message")
// Check if external providers exist
var providerCount int64
if err := h.DB.Model(&db.AuthProvider{}).Where("enabled = ?", true).Count(&providerCount).Error; err != nil {
log.Printf("Error counting auth providers: %v", err)
// Assume no providers if there's an error, or handle differently
providerCount = 0
}
hasExternalProviders := providerCount > 0
// User is not logged in, show login page
if message != "" {
components.Login(ctx, message).Render(c.Request.Context(), c.Writer)
components.Login(ctx, message, hasExternalProviders).Render(c.Request.Context(), c.Writer)
} else {
components.Login(ctx, "").Render(c.Request.Context(), c.Writer)
components.Login(ctx, "", hasExternalProviders).Render(c.Request.Context(), c.Writer)
}
}
@@ -291,10 +300,18 @@ func (h *Handlers) HandleLogin(c *gin.Context) {
email := c.PostForm("email")
password := c.PostForm("password")
// Check if external providers exist
var providerCount int64
if err := h.DB.Model(&db.AuthProvider{}).Where("enabled = ?", true).Count(&providerCount).Error; err != nil {
log.Printf("Error counting auth providers: %v", err)
providerCount = 0
}
hasExternalProviders := providerCount > 0
// Get user by email
var user db.User
if err := h.DB.Where("email = ?", email).First(&user).Error; err != nil {
components.Login(components.CreateTemplateContext(c), "Invalid credentials").Render(c, c.Writer)
components.Login(components.CreateTemplateContext(c), "Invalid credentials", hasExternalProviders).Render(c, c.Writer)
return
}
@@ -308,7 +325,7 @@ func (h *Handlers) HandleLogin(c *gin.Context) {
h.DB.Save(&user)
} else {
// Account is still locked
components.Login(components.CreateTemplateContext(c), "Account is locked due to too many failed login attempts. Please try again later.").Render(c, c.Writer)
components.Login(components.CreateTemplateContext(c), "Account is locked due to too many failed login attempts. Please try again later.", hasExternalProviders).Render(c, c.Writer)
return
}
}
@@ -325,12 +342,12 @@ func (h *Handlers) HandleLogin(c *gin.Context) {
lockoutTime := time.Now().Add(policy.LockoutDuration)
user.LockoutUntil = &lockoutTime
h.DB.Save(&user)
components.Login(components.CreateTemplateContext(c), "Account is locked due to too many failed login attempts. Please try again later.").Render(c, c.Writer)
components.Login(components.CreateTemplateContext(c), "Account is locked due to too many failed login attempts. Please try again later.", hasExternalProviders).Render(c, c.Writer)
return
}
h.DB.Save(&user)
components.Login(components.CreateTemplateContext(c), "Invalid credentials").Render(c, c.Writer)
components.Login(components.CreateTemplateContext(c), "Invalid credentials", hasExternalProviders).Render(c, c.Writer)
return
}
@@ -368,7 +385,7 @@ func (h *Handlers) HandleLogin(c *gin.Context) {
}
token, err := h.GenerateJWT(user.ID, user.Email, isAdmin)
if err != nil {
components.Login(components.CreateTemplateContext(c), "Authentication error").Render(c, c.Writer)
components.Login(components.CreateTemplateContext(c), "Authentication error", hasExternalProviders).Render(c, c.Writer)
return
}