diff --git a/server/internal/api/auth.go b/server/internal/api/auth.go index 817a052..2aafbdc 100644 --- a/server/internal/api/auth.go +++ b/server/internal/api/auth.go @@ -158,6 +158,36 @@ func (h *Handler) Logout(c *gin.Context) { resp.OK(c, gin.H{"ok": true}) } +type changePasswordReq struct { + OldPassword string `json:"old_password" binding:"required"` + NewPassword string `json:"new_password" binding:"required,min=8,max=72"` +} + +// ChangePassword POST /api/v1/auth/password — 修改密码。 +func (h *Handler) ChangePassword(c *gin.Context) { + u := sessionUser(c) + var req changePasswordReq + if err := c.ShouldBindJSON(&req); err != nil { + resp.Fail(c, http.StatusBadRequest, "invalid input: "+err.Error()) + return + } + ok, err := h.a.Hasher.VerifyPassword(u.PasswordHash, req.OldPassword) + if err != nil || !ok { + resp.Fail(c, http.StatusBadRequest, "旧密码不正确") + return + } + hash, err := h.a.Hasher.HashPassword(req.NewPassword) + if err != nil { + resp.Fail(c, http.StatusInternalServerError, "failed to hash password") + return + } + if err := h.a.DB.Model(&store.User{}).Where("id = ?", u.ID).Update("password_hash", hash).Error; err != nil { + resp.Fail(c, http.StatusInternalServerError, "failed to update password") + return + } + resp.OK(c, gin.H{"ok": true}) +} + // Me GET /api/v1/auth/me func (h *Handler) Me(c *gin.Context) { u := sessionUser(c) diff --git a/server/internal/api/router.go b/server/internal/api/router.go index 626f5fa..6d14ef4 100644 --- a/server/internal/api/router.go +++ b/server/internal/api/router.go @@ -63,6 +63,7 @@ func NewRouter(a *app.App, gw *proxy.Gateway) *gin.Engine { auth.POST("/login", h.Login) auth.POST("/refresh", h.Refresh) auth.POST("/logout", h.Logout) + auth.POST("/password", middleware.SessionAuth(a), h.ChangePassword) auth.GET("/me", middleware.SessionAuth(a), h.Me) } diff --git a/web/src/views/console/SettingsView.vue b/web/src/views/console/SettingsView.vue new file mode 100644 index 0000000..14d9e1f --- /dev/null +++ b/web/src/views/console/SettingsView.vue @@ -0,0 +1,84 @@ + + + + + + 账户设置 + 个人资料与安全 + + + + 个人资料 + + + 用户名 + {{ auth.user?.username }} + + + 邮箱 + {{ auth.user?.email }} + + + 角色 + {{ auth.user?.role }} + + + 余额 + {{ fmtMoney(auth.user?.balance ?? 0) }} + + + 注册时间 + {{ fmtTime(auth.user?.created_at) }} + + + + + + 修改密码 + + + + + 更新密码 + + + +
个人资料与安全