channels: give kicked/banned/promoted/transferred users a real qts so their client applies it

updateChannelParticipant carries the account's qts per the MTProto spec, but
the server always sent Qts: 0, so real clients silently discarded it as a
stale duplicate -- the banned/kicked user's channel never vanished locally
and no correct "removed by admin" message showed, even though the update was
delivered successfully at the transport layer.

Add a durable per-device qts queue (channel_participant_event_queue) sharing
its qts number space with the existing secret-chat queue (one qts sequence
per device, per spec), and use it to stamp a correct, monotonically
increasing qts on the update for every device of the affected user -- for
channel bans/kicks, admin promotion/demotion, and ownership transfer. A
device offline when it happened can now recover the event via
updates.getDifference instead of missing it permanently.
This commit is contained in:
Astra 2026-09-15 15:43:52 +01:00
parent 97711c9d2e
commit 206bde18e0
16 changed files with 482 additions and 42 deletions

View file

@ -1360,7 +1360,8 @@ func run(logger *zap.Logger) error {
// 私聊端对端加密Secret Chat握手状态机 + qts 投递队列(盲中继)。
secretChatStore := postgres.NewSecretChatStore(pool)
encryptedQueueStore := postgres.NewEncryptedQueueStore(pool)
secretChatService := secretchatapp.NewService(secretChatStore, encryptedQueueStore)
channelParticipantQueueStore := postgres.NewChannelParticipantQueueStore(pool)
secretChatService := secretchatapp.NewService(secretChatStore, encryptedQueueStore, channelParticipantQueueStore)
// Passkey:凭据持久化走 postgres;一次性挑战走进程内内存(短 TTL,与 QR 登录 token
// 同属进程内一次性凭据,不跨实例)。
passkeyStore := postgres.NewPasskeyStore(pool)