From 8dae63ee7061279fe458dfe8750b86f37e54703b Mon Sep 17 00:00:00 2001 From: AskaEth Date: Wed, 9 Sep 2026 20:59:42 +0800 Subject: [PATCH] =?UTF-8?q?feat(server):=20passwd=20=E5=AD=90=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E6=94=AF=E6=8C=81=20-new-username=20=E5=90=8C?= =?UTF-8?q?=E6=97=B6=E6=94=B9=E7=94=A8=E6=88=B7=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/internal/auth/auth.go | 22 ++++++++++++++++++++++ server/passwd.go | 10 ++++++++++ 2 files changed, 32 insertions(+) diff --git a/server/internal/auth/auth.go b/server/internal/auth/auth.go index d8b3925..21dcff9 100644 --- a/server/internal/auth/auth.go +++ b/server/internal/auth/auth.go @@ -202,6 +202,28 @@ func (s *Service) SetPassword(ctx context.Context, username, password string, mu return s.RevokeUserSessions(ctx, id) } +// SetUsername 修改用户名(供本机管理入口免登录调用),并作废该用户全部会话。 +func (s *Service) SetUsername(ctx context.Context, oldUsername, newUsername string) error { + if newUsername == "" { + return fmt.Errorf("新用户名不能为空") + } + res, err := s.db.ExecContext(ctx, + `UPDATE users SET username = ?, updated_at = datetime('now') WHERE username = ?`, + newUsername, oldUsername) + if err != nil { + return fmt.Errorf("更新用户名: %w", err) + } + if n, err := res.RowsAffected(); err == nil && n == 0 { + return fmt.Errorf("用户 %s 不存在", oldUsername) + } + + var id int64 + if err := s.db.QueryRowContext(ctx, `SELECT id FROM users WHERE username = ?`, newUsername).Scan(&id); err != nil { + return fmt.Errorf("查询用户: %w", err) + } + return s.RevokeUserSessions(ctx, id) +} + // VerifyPassword 校验指定用户的原密码,不创建会话(供「修改密码」等场景使用)。 func (s *Service) VerifyPassword(ctx context.Context, userID int64, password string) error { var hash string diff --git a/server/passwd.go b/server/passwd.go index 006b8c9..4fccaa7 100644 --- a/server/passwd.go +++ b/server/passwd.go @@ -16,6 +16,7 @@ func runPasswd(args []string) error { fs := flag.NewFlagSet("passwd", flag.ExitOnError) configPath := fs.String("config", "config.yaml", "配置文件路径") username := fs.String("user", "admin", "用户名") + newUsername := fs.String("new-username", "", "同时把用户名改成这个(留空则不改)") password := fs.String("password", "", "新密码;留空则随机生成并打印") if err := fs.Parse(args); err != nil { return err @@ -45,6 +46,15 @@ func runPasswd(args []string) error { } svc := auth.New(st.DB(), auth.Options{}) + + if *newUsername != "" && *newUsername != *username { + if err := svc.SetUsername(context.Background(), *username, *newUsername); err != nil { + return err + } + fmt.Printf("已将用户名 %s 改为 %s\n", *username, *newUsername) + *username = *newUsername + } + if err := svc.SetPassword(context.Background(), *username, pwd, generated); err != nil { return err }