refactor(server): decouple services and improve architecture
- Introduce interfaces for all major services (JWT, PostAI, Comment, Message, Notification, QRCodeLogin, Upload, Vote, etc.) to support dependency inversion.
- Move query parameters from `internal/dto` to a new `internal/query` package to separate request payloads from data transfer objects.
- Refactor `internal/router` to use embedded `RouterDeps` for cleaner dependency management.
- Decouple handlers from repositories by injecting services instead of direct repository access, ensuring proper layering.
- Improve database initialization by moving it from `internal/model` to `internal/database`.
- Optimize message decryption by implementing a more efficient `BatchDecrypt` method in `MessageEncryptor` using a worker pool.
- Enhance error handling and security by implementing fail-fast checks for encryption key length during startup.
- Clean up unused code, including the `avatar` package and several unused DTOs.
2026-06-15 03:41:59 +08:00
|
|
|
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"`
|
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
|
|
|
IsMember bool `json:"is_member"`
|
refactor(server): decouple services and improve architecture
- Introduce interfaces for all major services (JWT, PostAI, Comment, Message, Notification, QRCodeLogin, Upload, Vote, etc.) to support dependency inversion.
- Move query parameters from `internal/dto` to a new `internal/query` package to separate request payloads from data transfer objects.
- Refactor `internal/router` to use embedded `RouterDeps` for cleaner dependency management.
- Decouple handlers from repositories by injecting services instead of direct repository access, ensuring proper layering.
- Improve database initialization by moving it from `internal/model` to `internal/database`.
- Optimize message decryption by implementing a more efficient `BatchDecrypt` method in `MessageEncryptor` using a worker pool.
- Enhance error handling and security by implementing fail-fast checks for encryption key length during startup.
- Clean up unused code, including the `avatar` package and several unused DTOs.
2026-06-15 03:41:59 +08:00
|
|
|
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"`
|
|
|
|
|
}
|