fix(gateway): смена пароля не закрывает сессию текущего устройства

ChangePassword отзывает остальные сессии, но обработчик закрывал соединения
всех устройств пользователя — включая то, с которого пароль сменили: страница
теряла шлюз в момент успешного ответа, и подтверждение «Пароль изменён» не
показывалось (пункт 12 матрицы 11.6, меняли пароль через интерфейс).

Добавлен InvalidateUserExcept: текущее соединение опознаётся по хэшу токена
сессии, который теперь хранит и буфер RESUME. Для logout-all, бана и
админского сброса поведение прежнее — закрываются все соединения.

Тест: TestInvalidateUserExceptKeepsCurrentSession (второе устройство получает
INVALID_SESSION, текущее продолжает отвечать на heartbeat).
This commit is contained in:
2026-09-22 21:58:23 +03:00
parent a7b4e3318e
commit 05409d0914
4 changed files with 85 additions and 13 deletions
+4 -2
View File
@@ -270,9 +270,11 @@ func (s *Server) registerUserRoutes(api huma.API) {
if err := s.auth.ChangePassword(ctx, user.ID, session.ID, input.Body.CurrentPassword, input.Body.NewPassword); err != nil {
return nil, humaError(err)
}
// Смена пароля отзывает остальные сессии: соединения закрываем сразу.
// Смена пароля отзывает остальные сессии: их соединения закрываем сразу,
// а устройство, с которого пароль сменили, продолжает работать
// (AGENT.md 7.1, 11.6).
if s.gateway != nil {
s.gateway.InvalidateUser(user.ID, "password_changed")
s.gateway.InvalidateUserExcept(user.ID, session.TokenHash, "password_changed")
}
return newOKOutput(), nil
})