69 lines
1.7 KiB
Go
69 lines
1.7 KiB
Go
package helps
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"regexp"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
var claudeMetadataDeviceIDPattern = regexp.MustCompile(`^[a-f0-9]{64}$`)
|
|
|
|
type claudeMetadataUserID struct {
|
|
DeviceID string `json:"device_id"`
|
|
AccountUUID string `json:"account_uuid"`
|
|
SessionID string `json:"session_id"`
|
|
}
|
|
|
|
// generateFakeUserID generates metadata.user_id in the JSON string format used
|
|
// by Claude Code 2.1.78 and newer.
|
|
func generateFakeUserID() string {
|
|
return generateFakeUserIDWithSessionID(uuid.New().String())
|
|
}
|
|
|
|
func generateFakeUserIDWithSessionID(sessionID string) string {
|
|
if _, errParse := uuid.Parse(sessionID); errParse != nil {
|
|
sessionID = uuid.New().String()
|
|
}
|
|
hexBytes := make([]byte, 32)
|
|
_, _ = rand.Read(hexBytes)
|
|
value, _ := json.Marshal(claudeMetadataUserID{
|
|
DeviceID: hex.EncodeToString(hexBytes),
|
|
AccountUUID: "",
|
|
SessionID: sessionID,
|
|
})
|
|
return string(value)
|
|
}
|
|
|
|
// isValidUserID checks the Claude Code 2.1.220 metadata.user_id shape.
|
|
func isValidUserID(userID string) bool {
|
|
var value claudeMetadataUserID
|
|
if errUnmarshal := json.Unmarshal([]byte(userID), &value); errUnmarshal != nil {
|
|
return false
|
|
}
|
|
if !claudeMetadataDeviceIDPattern.MatchString(value.DeviceID) {
|
|
return false
|
|
}
|
|
if _, errParse := uuid.Parse(value.SessionID); errParse != nil {
|
|
return false
|
|
}
|
|
if value.AccountUUID == "" {
|
|
return true
|
|
}
|
|
_, errParse := uuid.Parse(value.AccountUUID)
|
|
return errParse == nil
|
|
}
|
|
|
|
func GenerateFakeUserID() string {
|
|
return generateFakeUserID()
|
|
}
|
|
|
|
func GenerateFakeUserIDWithSessionID(sessionID string) string {
|
|
return generateFakeUserIDWithSessionID(sessionID)
|
|
}
|
|
|
|
func IsValidUserID(userID string) bool {
|
|
return isValidUserID(userID)
|
|
}
|