451da3d26d
Support for service accounts with static credentials * feature complete * tests and docs * lint fix
78 lines
2.5 KiB
Go
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
|
|
}
|