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
All checks were successful
Automated Container Build / build-and-push (push) Successful in 1m19s
This commit is contained in:
parent
425598c278
commit
c3b1fe8de1
5 changed files with 226 additions and 26 deletions
|
|
@ -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(¤tHash); 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) {
|
||||
|
|
|
|||
|
|
@ -128,6 +128,9 @@ func main() {
|
|||
// Token refresh
|
||||
protected.Post("/auth/refresh", authHandler.Refresh)
|
||||
|
||||
// Password management
|
||||
protected.Put("/auth/password", authHandler.ChangePassword)
|
||||
|
||||
// 2FA management
|
||||
protected.Post("/auth/2fa/enable", authHandler.Enable2FA)
|
||||
protected.Post("/auth/2fa/confirm", authHandler.Confirm2FA)
|
||||
|
|
|
|||
Reference in a new issue