fix(gateway): смена пароля не закрывает сессию текущего устройства
ChangePassword отзывает остальные сессии, но обработчик закрывал соединения всех устройств пользователя — включая то, с которого пароль сменили: страница теряла шлюз в момент успешного ответа, и подтверждение «Пароль изменён» не показывалось (пункт 12 матрицы 11.6, меняли пароль через интерфейс). Добавлен InvalidateUserExcept: текущее соединение опознаётся по хэшу токена сессии, который теперь хранит и буфер RESUME. Для logout-all, бана и админского сброса поведение прежнее — закрываются все соединения. Тест: TestInvalidateUserExceptKeepsCurrentSession (второе устройство получает INVALID_SESSION, текущее продолжает отвечать на heartbeat).
This commit is contained in:
@@ -325,7 +325,7 @@ func (s *Service) register(session *clientSession, tokenHash string) {
|
||||
s.sessions[session.id] = session
|
||||
buffer, ok := s.buffers[tokenHash]
|
||||
if !ok {
|
||||
buffer = newResumeBuffer(ResumeBufferSize)
|
||||
buffer = newResumeBuffer(ResumeBufferSize, tokenHash)
|
||||
s.buffers[tokenHash] = buffer
|
||||
}
|
||||
// Владелец буфера нужен, чтобы доставлять адресные события (SendToUser)
|
||||
@@ -347,7 +347,7 @@ func (s *Service) bufferFor(tokenHash string) *resumeBuffer {
|
||||
if buffer, ok := s.buffers[tokenHash]; ok {
|
||||
return buffer
|
||||
}
|
||||
buffer := newResumeBuffer(ResumeBufferSize)
|
||||
buffer := newResumeBuffer(ResumeBufferSize, tokenHash)
|
||||
s.buffers[tokenHash] = buffer
|
||||
return buffer
|
||||
}
|
||||
@@ -405,11 +405,14 @@ func newSessionID() string {
|
||||
|
||||
// resumeBuffer хранит последние события для RESUME (AGENT.md 8.3).
|
||||
type resumeBuffer struct {
|
||||
mu sync.Mutex
|
||||
owner uint64
|
||||
limit int
|
||||
items []bufferedEvent
|
||||
updated time.Time
|
||||
mu sync.Mutex
|
||||
// tokenHash — сессия пользователя, которой принадлежит буфер: по нему
|
||||
// адресные отзывы отличают текущее соединение от остальных.
|
||||
tokenHash string
|
||||
owner uint64
|
||||
limit int
|
||||
items []bufferedEvent
|
||||
updated time.Time
|
||||
}
|
||||
|
||||
type bufferedEvent struct {
|
||||
@@ -417,8 +420,8 @@ type bufferedEvent struct {
|
||||
payload []byte
|
||||
}
|
||||
|
||||
func newResumeBuffer(limit int) *resumeBuffer {
|
||||
return &resumeBuffer{limit: limit, updated: time.Now()}
|
||||
func newResumeBuffer(limit int, tokenHash string) *resumeBuffer {
|
||||
return &resumeBuffer{limit: limit, tokenHash: tokenHash, updated: time.Now()}
|
||||
}
|
||||
|
||||
func (b *resumeBuffer) append(seq int64, payload []byte) {
|
||||
|
||||
Reference in New Issue
Block a user