fix(realtime): события ролей, комнат и отзыв сессий без перезагрузки

Дефекты, найденные e2e-матрицей AGENT.md 11.6 (пункты 1, 2, 7, 12):

- ROLE_CREATE/ROLE_UPDATE уходили телом роли без guild_id, а клиент ждал
  ссылку {guild_id, role_id} — событие отбрасывалось, роли у второго
  участника не обновлялись. В rolePayload добавлено guild_id, parseRoleEvent
  принимает и тело роли, и старую ссылку;
- выдача роли (MEMBER_UPDATE) и правки ролей не перечитывали список комнат,
  поэтому приватная комната не появлялась в сайдбаре без F5 — теперь клиент
  перечитывает комнаты по этим событиям;
- CHANNEL_CREATE/CHANNEL_UPDATE уходили телом комнаты с нулевым can_view
  (права персональные), и клиент прятал комнату по этому признаку. Сервер
  шлёт тело события без вычисленных прав плюс GUILD_CHANNELS_SYNC, а клиент
  по событию комнаты перечитывает список;
- отзыв сессий (logout-all, смена пароля, админский сброс и «выйти везде»,
  бан, удаление) не доходил до Gateway: второе устройство оставалось в
  приложении. Добавлен gateway.InvalidateUser — клиент получает
  INVALID_SESSION и закрывает соединение; клиент дополнительно обрабатывает
  событие SESSION_INVALIDATED.

Тесты: gateway (отзыв сессий закрывает соединения и не задевает чужого),
web (событие SESSION_INVALIDATED, перечитывание комнат по CHANNEL_CREATE).
This commit is contained in:
2026-09-22 20:10:53 +03:00
parent ff2fc878b0
commit d241714a6d
10 changed files with 188 additions and 26 deletions
+4
View File
@@ -247,6 +247,10 @@ func (s *Server) handleLogoutAll(w http.ResponseWriter, r *http.Request) {
writeAPIError(w, err)
return
}
// Другие устройства должны узнать об отзыве сессий сразу (AGENT.md 11.6).
if s.gateway != nil {
s.gateway.InvalidateUser(user.ID, "logout_all")
}
http.SetCookie(w, s.clearSessionCookie())
writeJSON(w, map[string]any{"ok": true})
}