vibe-proxy/backend/sdk/cliproxy/auth/token_fingerprint.go
2026-08-24 00:10:41 +02:00

72 lines
2.1 KiB
Go

package auth
import (
"context"
"crypto/sha256"
"encoding/hex"
"strings"
)
// AccessTokenSHA256 returns the normalized OAuth access-token fingerprint used
// to fence asynchronous Home execution results without exposing the token.
func AccessTokenSHA256(auth *Auth) string {
accessToken := accessTokenForFingerprint(auth)
if accessToken == "" {
return ""
}
digest := sha256.Sum256([]byte(accessToken))
return hex.EncodeToString(digest[:])
}
type accessTokenFingerprintObserverContextKey struct{}
func withAccessTokenFingerprintObserver(ctx context.Context, observer func(*Auth)) context.Context {
if ctx == nil {
ctx = context.Background()
}
if observer == nil {
return ctx
}
return context.WithValue(ctx, accessTokenFingerprintObserverContextKey{}, observer)
}
// NotifyAccessTokenFingerprint reports the auth snapshot actually used by an
// executor that may refresh its local token before sending upstream. The
// observer derives the fingerprint and can reuse that snapshot for recovery.
func NotifyAccessTokenFingerprint(ctx context.Context, auth *Auth) {
if ctx == nil || auth == nil || AccessTokenSHA256(auth) == "" {
return
}
observer, _ := ctx.Value(accessTokenFingerprintObserverContextKey{}).(func(*Auth))
if observer != nil {
observer(auth.Clone())
}
}
func accessTokenForFingerprint(auth *Auth) string {
if auth == nil || auth.Metadata == nil {
return ""
}
for _, key := range []string{"access_token", "accessToken"} {
if value, ok := auth.Metadata[key].(string); ok && strings.TrimSpace(value) != "" {
return strings.TrimSpace(value)
}
}
for _, key := range []string{"token", "Token"} {
switch token := auth.Metadata[key].(type) {
case map[string]any:
for _, tokenKey := range []string{"access_token", "accessToken"} {
if value, ok := token[tokenKey].(string); ok && strings.TrimSpace(value) != "" {
return strings.TrimSpace(value)
}
}
case map[string]string:
for _, tokenKey := range []string{"access_token", "accessToken"} {
if value := strings.TrimSpace(token[tokenKey]); value != "" {
return value
}
}
}
}
return ""
}