mirror of
https://github.com/warmbly/warmbly.git
synced 2026-09-06 16:01:28 +00:00
Add authenticated session listing and revocation APIs, track the auth provider on sessions, and expose active session controls in account security settings.
67 lines
1.6 KiB
Go
67 lines
1.6 KiB
Go
package token
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/warmbly/warmbly/internal/errx"
|
|
"github.com/warmbly/warmbly/internal/models"
|
|
)
|
|
|
|
func (s *tokenService) GetSession(ctx context.Context, sessionID uuid.UUID) (*models.Session, *errx.Error) {
|
|
sess, err := s.getSession(ctx, sessionID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if sess != nil {
|
|
return sess, nil
|
|
}
|
|
|
|
sess, err = s.tokenRepository.GetSession(ctx, sessionID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := s.saveSession(ctx, sess, SessionTTL); err != nil {
|
|
return nil, err
|
|
}
|
|
return sess, nil
|
|
}
|
|
|
|
func sameTokenIssueTime(a, b time.Time) bool {
|
|
// JWT issued-at precision can differ from DB timestamp precision.
|
|
// Compare at second precision to avoid false mismatches.
|
|
return a.UTC().Truncate(time.Second).Equal(b.UTC().Truncate(time.Second))
|
|
}
|
|
|
|
func (s *tokenService) ValidateAccessToken(ctx context.Context, accessToken string) (*models.Session, *errx.Error) {
|
|
t, err := s.VerifyToken(accessToken)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if t.ExpiresAt.Before(time.Now()) {
|
|
return nil, errx.ErrToken
|
|
}
|
|
|
|
session, err := s.GetSession(ctx, t.SessionID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// A revoked session is dead immediately. Revocation busts the Redis cache,
|
|
// so the next read here re-loads the row with revoked_at set and the token
|
|
// stops working without waiting for the cache TTL or a refresh.
|
|
if session.RevokedAt != nil {
|
|
return nil, errx.ErrToken
|
|
}
|
|
|
|
if session.AccessNonce != t.Nonce || !sameTokenIssueTime(session.LastRefreshedAt, t.IssuedAt.Time) {
|
|
return nil, errx.ErrToken
|
|
}
|
|
|
|
return session, nil
|
|
}
|