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
121 lines
3.7 KiB
Go
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"`
|
|
}
|