package cachevalkey import ( "context" "time" ) // blacklistShape mirrors auth-jwt.Blacklist for compile-time duck-type verification. // Cache-valkey must not import auth-jwt (D-1), so the shape is defined locally. type blacklistShape interface { IsRevoked(ctx context.Context, jti string) (bool, error) Revoke(ctx context.Context, jti string, ttl time.Duration) error } var _ blacklistShape = (*Blacklist)(nil) // Blacklist is a Valkey-backed JWT refresh token revocation list. // Satisfies auth-jwt.Blacklist via duck typing — no import of that package required. // // JTIs are stored as keys with their remaining TTL; the entry expires naturally // when the token would have expired. Keys are stored as-is (JTIs are UUIDs and // do not collide with permission cache keys). type Blacklist struct { provider Provider } // NewBlacklist returns a Blacklist backed by p. func NewBlacklist(p Provider) *Blacklist { return &Blacklist{provider: p} } // IsRevoked reports whether the refresh token identified by jti has been revoked. func (b *Blacklist) IsRevoked(ctx context.Context, jti string) (bool, error) { return b.provider.Exists(ctx, jti) } // Revoke marks jti as revoked for the given TTL. // TTL should match the token's remaining lifetime so the entry expires naturally. func (b *Blacklist) Revoke(ctx context.Context, jti string, ttl time.Duration) error { return b.provider.Set(ctx, jti, "1", ttl) }