Files
2026-10-03 12:37:38 +08:00

65 lines
1.7 KiB
Go

package cli
import (
"errors"
"flag"
"fmt"
"strings"
"gorm.io/gorm"
"alterminal/internal/auth"
"alterminal/internal/store"
)
// runUpdatePassword 解析旗標並重設指定帳號的密碼。此為管理用指令,
// 不需驗證舊密碼;密碼更新成功後一併撤銷該使用者所有 Session,
// 避免既有登入在密碼重設後續存。
func runUpdatePassword(args []string) error {
fs := flag.NewFlagSet("update-password", flag.ExitOnError)
username := fs.String("username", "", "登入帳號(必填)")
password := fs.String("password", "", "新密碼(選填;省略時於終端機輸入)")
fs.Parse(args)
name := strings.TrimSpace(*username)
if name == "" {
return errors.New("username 不可為空")
}
pw, err := resolvePassword(*password)
if err != nil {
return err
}
db, err := store.Open()
if err != nil {
return fmt.Errorf("database: %w", err)
}
u, err := findUserByUsername(db, name)
if err != nil {
return err
}
if err := u.SetPassword(pw); err != nil {
return fmt.Errorf("hash password: %w", err)
}
revoked, err := auth.UpdateUserPassword(db, u)
if err != nil {
return err
}
fmt.Printf("密碼更新成功:id=%d username=%s(已撤銷 %d 個 Session)\n", u.ID, u.Username, revoked)
return nil
}
// findUserByUsername 以帳號查詢使用者,查無時回傳可讀的錯誤。
func findUserByUsername(db *gorm.DB, username string) (*auth.User, error) {
var u auth.User
err := db.Where("username = ?", username).First(&u).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, fmt.Errorf("username %q 不存在", username)
}
if err != nil {
return nil, fmt.Errorf("query user: %w", err)
}
return &u, nil
}