Files
backend/internal/dto/group_dto.go
lafay eb931bf1c6
All checks were successful
Build Backend / build (push) Successful in 2m19s
Build Backend / build-docker (push) Successful in 46s
feat(auth): implement session-based token management with revocation support
Add Session model, SessionService, and SessionRepository to track user login
sessions and enable token revocation on auth-critical events.

- Introduce explicit TokenType (access/refresh) in JWT claims to prevent
  refresh token misuse via access token endpoints
- Add SessionID field to JWT claims, enabling stateless JWT validation
  against revoked sessions
- Replace legacy Auth middleware with RequireAuth/OptionalAuth pipeline
  that validates token type, account status, and session validity
- Implement session revocation on password change, reset, user ban/inactive,
  and explicit logout
- Add Principal cache with active invalidation for banned/role-changed users
- Fix IDOR vulnerability: GetMessagesByCursor now validates currentUserID
  is conversation participant via GetParticipantStrict
- Add group member visibility checks: announcements, group info, member list
  now require group membership
- Simplify Casbin policy: remove g grouping, use r.sub == p.sub matcher
  with globMatch; user_roles table is single source of truth for roles
- Add migration logic to clean legacy casbin g rules and migrate old p rules
  from path-style to admin/<domain> resource naming
2026-07-05 18:28:08 +08:00

121 lines
3.7 KiB
Go

package dto
// ==================== Group DTOs ====================
// 从 dto.go 拆分而来:群组相关的请求与响应 DTO。
// 与 group_converter.go 同属群组域。
// CreateGroupRequest 创建群组请求
type CreateGroupRequest struct {
Name string `json:"name" binding:"required,max=50"`
Description string `json:"description" binding:"max=500"`
MemberIDs []string `json:"member_ids"`
}
// UpdateGroupRequest 更新群组请求
type UpdateGroupRequest struct {
Name string `json:"name" binding:"omitempty,max=50"`
Description string `json:"description" binding:"omitempty,max=500"`
Avatar string `json:"avatar" binding:"omitempty,url"`
}
// InviteMembersRequest 邀请成员请求
type InviteMembersRequest struct {
MemberIDs []string `json:"member_ids" binding:"required,min=1"`
}
// TransferOwnerRequest 转让群主请求
type TransferOwnerRequest struct {
NewOwnerID string `json:"new_owner_id" binding:"required"`
}
// SetRoleRequest 设置角色请求
type SetRoleRequest struct {
Role string `json:"role" binding:"required,oneof=admin member"`
}
// SetNicknameRequest 设置昵称请求
type SetNicknameRequest struct {
Nickname string `json:"nickname" binding:"max=50"`
}
// MuteMemberRequest 禁言成员请求
type MuteMemberRequest struct {
Muted bool `json:"muted"`
}
// SetMuteAllRequest 设置全员禁言请求
type SetMuteAllRequest struct {
MuteAll bool `json:"mute_all"`
}
// SetJoinTypeRequest 设置加群方式请求
type SetJoinTypeRequest struct {
JoinType int `json:"join_type" binding:"min=0,max=2"`
}
// CreateAnnouncementRequest 创建群公告请求
type CreateAnnouncementRequest struct {
Content string `json:"content" binding:"required,max=2000"`
}
// GroupResponse 群组响应
type GroupResponse struct {
ID string `json:"id"`
Name string `json:"name"`
Avatar string `json:"avatar"`
Description string `json:"description"`
OwnerID string `json:"owner_id"`
MemberCount int `json:"member_count"`
MaxMembers int `json:"max_members"`
JoinType int `json:"join_type"`
MuteAll bool `json:"mute_all"`
IsMember bool `json:"is_member"`
CreatedAt string `json:"created_at"`
}
// GroupMemberResponse 群成员响应
type GroupMemberResponse struct {
ID string `json:"id"`
GroupID string `json:"group_id"`
UserID string `json:"user_id"`
Role string `json:"role"`
Nickname string `json:"nickname"`
Muted bool `json:"muted"`
JoinTime string `json:"join_time"`
User *UserResponse `json:"user,omitempty"`
}
// GroupAnnouncementResponse 群公告响应
type GroupAnnouncementResponse struct {
ID string `json:"id"`
GroupID string `json:"group_id"`
Content string `json:"content"`
AuthorID string `json:"author_id"`
IsPinned bool `json:"is_pinned"`
CreatedAt string `json:"created_at"`
}
// GroupListResponse 群组列表响应
type GroupListResponse struct {
List []*GroupResponse `json:"list"`
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"page_size"`
}
// GroupMemberListResponse 群成员列表响应
type GroupMemberListResponse struct {
List []*GroupMemberResponse `json:"list"`
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"page_size"`
}
// GroupAnnouncementListResponse 群公告列表响应
type GroupAnnouncementListResponse struct {
List []*GroupAnnouncementResponse `json:"list"`
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"page_size"`
}