feat: implement precise token logout

This commit is contained in:
richjohnrambo
2026-09-10 09:43:02 +08:00
parent 98234db263
commit 6b2f1e06e0
8 changed files with 107 additions and 15 deletions
+28
View File
@@ -2,6 +2,8 @@ package store
import (
"context"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"sort"
@@ -78,6 +80,7 @@ type groupMessageRuntime interface {
AllowRate(tenantID types.TenantID, scope string, limit int, window time.Duration) (bool, int, time.Duration, error)
ClaimShortState(namespace, id string, ttl time.Duration) (bool, error)
ClaimShortStateValue(namespace, id, value string, ttl time.Duration) (bool, bool, error)
ShortStateExists(namespace, id string) (bool, error)
}
var groupMsgRuntime groupMessageRuntime
@@ -146,6 +149,26 @@ func ClaimShortStateValue(namespace, id, value string, ttl time.Duration) (bool,
return claimed, sameValue, true, err
}
func RevokeLoginToken(tenantID types.TenantID, token []byte, ttl time.Duration) (bool, error) {
if groupMsgRuntime == nil || !tenantID.IsValid() || len(token) == 0 || ttl <= 0 {
return false, nil
}
digest := sha256.Sum256(token)
id := strconv.FormatInt(int64(tenantID), 10) + ":" + hex.EncodeToString(digest[:])
_, err := groupMsgRuntime.ClaimShortState("revoked_login_token", id, ttl)
return true, err
}
func IsLoginTokenRevoked(tenantID types.TenantID, token []byte) (bool, bool, error) {
if groupMsgRuntime == nil || !tenantID.IsValid() || len(token) == 0 {
return false, false, nil
}
digest := sha256.Sum256(token)
id := strconv.FormatInt(int64(tenantID), 10) + ":" + hex.EncodeToString(digest[:])
revoked, err := groupMsgRuntime.ShortStateExists("revoked_login_token", id)
return revoked, true, err
}
func RefreshUserPresence(tenantID types.TenantID, uid types.Uid, sid, nodeID string) error {
if groupMsgRuntime == nil || !tenantID.IsValid() || uid.IsZero() || sid == "" {
return nil
@@ -881,6 +904,11 @@ func (r *redisGroupMessageRuntime) ClaimShortStateValue(namespace, id, value str
return false, existing == value, nil
}
func (r *redisGroupMessageRuntime) ShortStateExists(namespace, id string) (bool, error) {
count, err := r.client.Exists(context.Background(), r.shortStateKey(namespace, id)).Result()
return count > 0, err
}
func (r *redisGroupMessageRuntime) hotSeqIDs(tenantID types.TenantID, topic string, opts *types.QueryOpt, limit int) ([]int64, bool, error) {
if opts != nil && len(opts.IdRanges) > 0 {
seqs := expandRanges(opts.IdRanges, limit)