fix(organize): strip release tags/roman numerals/season markers; de-hardcode paths

feat(bot): button menu, capacity/open-reg quota, redemption codes, user mgmt,
account expiry + signin streak, device anti-sharing + inactivity cleanup,
one-click kick, self-service username/password

- Consolidate organize/rename defaults into Tools panel

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
shuk shuk
2026-05-30 17:57:17 +00:00
committed by Shuke
parent f1d87638f3
commit 22b64d3d47
22 changed files with 2353 additions and 133 deletions
+5
View File
@@ -38,6 +38,7 @@ var (
ErrUsernameTaken = errors.New("username already taken")
ErrUserInactive = errors.New("user account is inactive")
ErrUserLimitReached = errors.New("user limit reached")
ErrUserExpired = errors.New("user account has expired")
)
// MaxUsers is kept for compatibility with tests and callers; dynamic runtime
@@ -150,6 +151,10 @@ func (s *AuthService) Login(ctx context.Context, username, password string) (*Lo
if !u.IsActive {
return nil, ErrUserInactive
}
// 账号到期则停用登录,直到管理员或兑换码续期。
if u.ExpiredAt != nil && time.Now().After(*u.ExpiredAt) {
return nil, ErrUserExpired
}
if err := bcrypt.CompareHashAndPassword([]byte(u.PasswordHash), []byte(password)); err != nil {
return nil, ErrInvalidCredentials
}