fix: sync support private chat content protection
This commit is contained in:
parent
74c9249091
commit
037ce017d4
25 changed files with 1395 additions and 36 deletions
|
|
@ -56,8 +56,9 @@ const tdesktopClient = "tdesktop"
|
|||
// WebK directly calls Array.some on fragment_prefixes while rendering user profiles,
|
||||
// so this compatibility key must always remain an array, even when it is empty.
|
||||
const tdesktopDefaultAppConfigBase = `{"chat_read_mark_expire_period":604800,"chat_read_mark_size_threshold":50,"pm_read_date_expire_period":604800,"quote_length_max":1024,"telegram_antispam_group_size_min":200,"telegram_antispam_user_id":"5434988373","fragment_prefixes":["888"],"forum_upgrade_participants_min":2,"reactions_default":{"_":"reactionEmoji","emoticon":"👍"},"reactions_uniq_max":11,"reactions_user_max_default":1,"reactions_user_max_premium":3,"reactions_in_chat_max":3,"boosts_channel_level_max":100,"rich_message_posting":"enabled","upload_markup_video":true,"emojies_send_dice":["🎲","🎯","🏀","⚽","⚽️","🎳","🎰"],"premium_purchase_blocked":false,"stars_purchase_blocked":false,"stargifts_blocked":false,"stargifts_pinned_to_top_limit":6,"stories_stealth_future_period":1500,"stories_stealth_past_period":300,"stories_stealth_cooldown_period":10800,"quick_replies_limit":100,"quick_reply_messages_limit":20,"business_chat_links_limit":100,"dialog_filters_enabled":true,"chatlist_update_period":3600,"chatlist_invites_limit_default":3,"chatlist_invites_limit_premium":20,"chatlists_joined_limit_default":2,"chatlists_joined_limit_premium":20,"about_length_limit_default":70,"about_length_limit_premium":140,"bot_verification_description_length_limit":70,"caption_length_limit_default":1024,"caption_length_limit_premium":4096,"channels_limit_default":500,"channels_limit_premium":1000,"channels_public_limit_default":10,"channels_public_limit_premium":20,"dialog_filters_limit_default":10,"dialog_filters_limit_premium":20,"dialog_filters_chats_limit_default":100,"dialog_filters_chats_limit_premium":200,"dialogs_pinned_limit_default":5,"dialogs_pinned_limit_premium":10,"dialogs_folder_pinned_limit_default":100,"dialogs_folder_pinned_limit_premium":200,"saved_dialogs_pinned_limit_default":5,"saved_dialogs_pinned_limit_premium":100,"saved_gifs_limit_default":200,"saved_gifs_limit_premium":400,"stickers_faved_limit_default":5,"stickers_faved_limit_premium":10,"recommended_channels_limit_default":10,"recommended_channels_limit_premium":100,"aicompose_tone_examples_num":3,"aicompose_tone_title_length_max":12,"aicompose_tone_prompt_length_max":1024,"aicompose_tone_saved_limit_default":5,"aicompose_tone_saved_limit_premium":20,"upload_max_fileparts_default":4000,"upload_max_fileparts_premium":8000`
|
||||
const tdesktopNoForwardsAppConfig = `,"no_forwards_request_expire_period":86400`
|
||||
|
||||
const defaultAppConfigHash = 25 // 默认 app config 内容变更时必须递增,否则缓存端只会收到 notModified。
|
||||
const defaultAppConfigHash = 26 // 默认 app config 内容变更时必须递增,否则缓存端只会收到 notModified。
|
||||
|
||||
// Service 提供客户端启动配置与国家区号目录。
|
||||
//
|
||||
|
|
@ -117,14 +118,14 @@ func defaultAppConfig(mapboxToken string) domain.AppConfig {
|
|||
|
||||
func defaultAppConfigJSON(mapboxToken string) []byte {
|
||||
if mapboxToken == "" {
|
||||
return []byte(tdesktopDefaultAppConfigBase + `}`)
|
||||
return []byte(tdesktopDefaultAppConfigBase + tdesktopNoForwardsAppConfig + `}`)
|
||||
}
|
||||
token, err := json.Marshal(mapboxToken)
|
||||
if err != nil {
|
||||
return []byte(tdesktopDefaultAppConfigBase + `}`)
|
||||
return []byte(tdesktopDefaultAppConfigBase + tdesktopNoForwardsAppConfig + `}`)
|
||||
}
|
||||
tokenJSON := string(token)
|
||||
return []byte(tdesktopDefaultAppConfigBase + `,"tdesktop_config_map":{"maps":` + tokenJSON + `,"geo":` + tokenJSON + `,"bmaps":` + tokenJSON + `,"bgeo":` + tokenJSON + `}}`)
|
||||
return []byte(tdesktopDefaultAppConfigBase + tdesktopNoForwardsAppConfig + `,"tdesktop_config_map":{"maps":` + tokenJSON + `,"geo":` + tokenJSON + `,"bmaps":` + tokenJSON + `,"bgeo":` + tokenJSON + `}}`)
|
||||
}
|
||||
|
||||
func defaultAppConfigHashFor(mapboxToken string) int {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"telesrv/internal/domain"
|
||||
)
|
||||
|
||||
// TestAppConfigPremiumKeys 断言 premium / Stars 相关 key 完整下发且 hash 已递增:
|
||||
|
|
@ -26,6 +28,9 @@ func TestAppConfigPremiumKeys(t *testing.T) {
|
|||
if err := json.Unmarshal(cfg.JSON, &decoded); err != nil {
|
||||
t.Fatalf("app config json invalid: %v", err)
|
||||
}
|
||||
if period, ok := decoded["no_forwards_request_expire_period"].(float64); !ok || int(period) != domain.PrivateNoForwardsRequestExpirePeriod {
|
||||
t.Fatalf("no_forwards_request_expire_period = %v, want %d", decoded["no_forwards_request_expire_period"], domain.PrivateNoForwardsRequestExpirePeriod)
|
||||
}
|
||||
if blocked, ok := decoded["premium_purchase_blocked"].(bool); !ok || blocked {
|
||||
t.Fatalf("premium_purchase_blocked = %v, want false (star gift 送礼入口耦合此 flag)", decoded["premium_purchase_blocked"])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -222,6 +222,42 @@ func (s *Service) SetChatTheme(ctx context.Context, userID int64, req domain.Set
|
|||
return out, nil
|
||||
}
|
||||
|
||||
// GetPrivateNoForwards returns the canonical content-protection state for one
|
||||
// ordinary private chat.
|
||||
func (s *Service) GetPrivateNoForwards(ctx context.Context, userID, peerUserID int64) (domain.PrivateNoForwardsState, error) {
|
||||
if s == nil || s.messages == nil || userID == 0 || peerUserID == 0 || userID == peerUserID {
|
||||
return domain.PrivateNoForwardsState{}, domain.ErrMessageIDInvalid
|
||||
}
|
||||
backend, ok := s.messages.(store.PrivateNoForwardsStore)
|
||||
if !ok {
|
||||
return domain.PrivateNoForwardsState{}, nil
|
||||
}
|
||||
return backend.GetPrivateNoForwards(ctx, userID, peerUserID)
|
||||
}
|
||||
|
||||
// TogglePrivateNoForwards atomically mutates the pair state and appends the
|
||||
// corresponding service message when the official state machine requires one.
|
||||
func (s *Service) TogglePrivateNoForwards(ctx context.Context, userID int64, req domain.TogglePrivateNoForwardsRequest) (domain.TogglePrivateNoForwardsResult, error) {
|
||||
if s == nil || s.messages == nil || userID == 0 {
|
||||
return domain.TogglePrivateNoForwardsResult{}, domain.ErrMessageIDInvalid
|
||||
}
|
||||
if req.ActorUserID == 0 {
|
||||
req.ActorUserID = userID
|
||||
}
|
||||
if req.ActorUserID != userID || req.PeerUserID == 0 || req.PeerUserID == userID ||
|
||||
req.RequestMsgID < 0 || req.RequestMsgID > domain.MaxMessageBoxID {
|
||||
return domain.TogglePrivateNoForwardsResult{}, domain.ErrMessageIDInvalid
|
||||
}
|
||||
if err := s.ensureCanSend(ctx, userID); err != nil {
|
||||
return domain.TogglePrivateNoForwardsResult{}, err
|
||||
}
|
||||
backend, ok := s.messages.(store.PrivateNoForwardsStore)
|
||||
if !ok {
|
||||
return domain.TogglePrivateNoForwardsResult{}, domain.ErrMessageIDInvalid
|
||||
}
|
||||
return backend.TogglePrivateNoForwards(ctx, req)
|
||||
}
|
||||
|
||||
func chatThemeServiceMedia(emoticon string) *domain.MessageMedia {
|
||||
return &domain.MessageMedia{
|
||||
Kind: domain.MessageMediaKindService,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue