Files
Jay Brown 451da3d26d Merged in feature/service-accounts-1 (pull request #227)
Support for service accounts with static credentials

* feature complete

* tests and docs

* lint fix
2026-05-21 19:40:04 +00:00

78 lines
2.5 KiB
Go

package cognitoauth
import (
"sync"
"time"
"github.com/lestrrat-go/jwx/v2/jwk"
)
// TokenResponse represents the response from the token endpoint
// Returned by Cognito when exchanging an authorization code for tokens
type TokenResponse struct {
IDToken string `json:"id_token"` // OpenID Connect ID token containing user claims
AccessToken string `json:"access_token"` // OAuth2 access token for accessing resources
RefreshToken string `json:"refresh_token"` // Token used to get new access tokens without re-authentication
ExpiresIn int `json:"expires_in"` // Token validity period in seconds
TokenType string `json:"token_type"` // Type of token, typically "Bearer"
}
// PKCESession stores PKCE code verifier for verification
// We need to store the code verifier temporarily to use during token exchange
type PKCESession struct {
CodeVerifier string
CreatedAt time.Time
ExpiresAt time.Time
}
// JWKSCache caches a JSON Web Key Set for a single URL.
// Implements a thread-safe caching mechanism with expiration.
type JWKSCache struct {
KeySet jwk.Set // The cached JSON Web Key Set
ExpiresAt time.Time // Expiration time for the cache
mutex sync.RWMutex // Mutex for thread-safe access
}
// jwksCacheMap stores per-URL JWKS caches so the verifier can serve
// multiple issuers (human pool A, service-accounts pool B) without
// the entries clobbering each other on lookup.
type jwksCacheMap struct {
sync.Mutex
entries map[string]*JWKSCache
}
func (m *jwksCacheMap) get(url string) *JWKSCache {
m.Lock()
defer m.Unlock()
c, ok := m.entries[url]
if !ok {
c = &JWKSCache{ExpiresAt: time.Now()}
m.entries[url] = c
}
return c
}
// Global map to store PKCE sessions by state parameter
// In a production environment, this should be replaced with a proper session store
var pkceSessionMap = struct {
sync.RWMutex
sessions map[string]*PKCESession
}{
sessions: make(map[string]*PKCESession),
}
// jwksCaches holds one cache entry per JWKS URL. The previous
// single-cache design silently returned a stale keyset whenever the
// caller asked for a *different* URL within the TTL — fine when only
// one Cognito pool existed, but unsafe under the two-pool plan.
var jwksCaches = &jwksCacheMap{
entries: make(map[string]*JWKSCache),
}
// UserInfo represents the user information extracted from JWT claims
type UserInfo struct {
Username string // Username from the token
Email string // Email from the token
Groups []string // Groups the user belongs to
}