Implement UI enhancements, change password settings, theme toggle, and custom grid size slider
All checks were successful
Automated Container Build / build-and-push (push) Successful in 1m19s

This commit is contained in:
Elijah 2026-05-22 18:22:21 -07:00
parent 425598c278
commit c3b1fe8de1
5 changed files with 226 additions and 26 deletions

View file

@ -245,6 +245,46 @@ func (h *AuthHandler) Disable2FA(c *fiber.Ctx) error {
return c.JSON(fiber.Map{"message": "2FA disabled successfully"})
}
// ChangePassword allows an authenticated user to change their password.
// PUT /api/auth/password
func (h *AuthHandler) ChangePassword(c *fiber.Ctx) error {
username := c.Locals("username").(string)
var req struct {
OldPassword string `json:"old_password"`
NewPassword string `json:"new_password"`
}
if err := c.BodyParser(&req); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "invalid request body"})
}
if len(req.NewPassword) < 8 {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "new password must be at least 8 characters"})
}
var currentHash string
if err := h.DB.QueryRow("SELECT password_hash FROM users WHERE username = ?", username).Scan(&currentHash); err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "database error"})
}
if !verifyPassword(req.OldPassword, currentHash) {
h.Guard.RecordFailure(c.IP())
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "incorrect current password"})
}
newHash, err := hashPassword(req.NewPassword)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "failed to hash new password"})
}
if _, err := h.DB.Exec("UPDATE users SET password_hash = ? WHERE username = ?", newHash, username); err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "failed to update password"})
}
h.DB.AddAuditLog("password_changed", fmt.Sprintf("User '%s' changed their password", username), c.IP())
return c.JSON(fiber.Map{"message": "password changed successfully"})
}
// --- Password Hashing with Argon2 ---
func hashPassword(password string) (string, error) {