pebaikan decription
This commit is contained in:
@@ -1,46 +1,50 @@
|
|||||||
package helper
|
package helper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/aes"
|
|
||||||
"crypto/cipher"
|
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/base64"
|
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
lzstring "github.com/daku10/go-lz-string"
|
lzstring "github.com/daku10/go-lz-string"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// StringDecrypt - langsung coba decompress tanpa decrypt ulang
|
||||||
func StringDecrypt(key string, encryptedString string) (string, error) {
|
func StringDecrypt(key string, encryptedString string) (string, error) {
|
||||||
keyHash := sha256.Sum256([]byte(key))
|
log.Printf("StringDecrypt: Attempting decompression, data length: %d", len(encryptedString))
|
||||||
keyHashBytes := keyHash[:]
|
|
||||||
|
|
||||||
iv := keyHashBytes[:16]
|
// Method 1: Try direct LZ-string decompression (data sudah didecrypt di response.go)
|
||||||
|
if result, err := lzstring.DecompressFromEncodedURIComponent(encryptedString); err == nil && len(result) > 0 {
|
||||||
encryptedBytes, err := base64.StdEncoding.DecodeString(encryptedString)
|
log.Printf("StringDecrypt: Direct decompression successful")
|
||||||
if err != nil {
|
return result, nil
|
||||||
return "", err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
block, err := aes.NewCipher(keyHashBytes)
|
// Method 2: Try other LZ-string methods
|
||||||
if err != nil {
|
if result, err := lzstring.DecompressFromBase64(encryptedString); err == nil && len(result) > 0 {
|
||||||
return "", err
|
log.Printf("StringDecrypt: Base64 decompression successful")
|
||||||
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
mode := cipher.NewCBCDecrypter(block, iv)
|
// Method 3: If all fail, return the original string
|
||||||
|
log.Printf("StringDecrypt: All decompression failed, returning original data")
|
||||||
decrypted := make([]byte, len(encryptedBytes))
|
return encryptedString, nil
|
||||||
mode.CryptBlocks(decrypted, encryptedBytes)
|
|
||||||
|
|
||||||
decrypted = RemovePKCS7Padding(decrypted)
|
|
||||||
|
|
||||||
dataResp, err := lzstring.DecompressFromEncodedURIComponent(string(decrypted))
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Error decompress: %v", err)
|
|
||||||
}
|
|
||||||
return dataResp, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func RemovePKCS7Padding(data []byte) []byte {
|
func RemovePKCS7Padding(data []byte) []byte {
|
||||||
|
if len(data) == 0 {
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
paddingLength := int(data[len(data)-1])
|
paddingLength := int(data[len(data)-1])
|
||||||
|
if paddingLength > len(data) || paddingLength == 0 {
|
||||||
|
log.Printf("RemovePKCS7Padding: Invalid padding length: %d, data length: %d", paddingLength, len(data))
|
||||||
|
return data // Return original data if padding is invalid
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify all padding bytes are correct
|
||||||
|
for i := len(data) - paddingLength; i < len(data); i++ {
|
||||||
|
if data[i] != byte(paddingLength) {
|
||||||
|
log.Printf("RemovePKCS7Padding: Invalid padding byte at position %d", i)
|
||||||
|
return data // Return original data if padding is invalid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return data[:len(data)-paddingLength]
|
return data[:len(data)-paddingLength]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
|
"unicode/utf16"
|
||||||
|
|
||||||
|
lzstring "github.com/daku10/go-lz-string"
|
||||||
)
|
)
|
||||||
|
|
||||||
func min(a, b int) int {
|
func min(a, b int) int {
|
||||||
@@ -23,7 +26,7 @@ func min(a, b int) int {
|
|||||||
// ResponseVclaim decrypts the encrypted response from VClaim API
|
// ResponseVclaim decrypts the encrypted response from VClaim API
|
||||||
func ResponseVclaim(encrypted string, key string) (string, error) {
|
func ResponseVclaim(encrypted string, key string) (string, error) {
|
||||||
log.Println("ResponseVclaim: Starting decryption process")
|
log.Println("ResponseVclaim: Starting decryption process")
|
||||||
log.Printf("ResponseVclaim: Encrypted string: %s", encrypted)
|
log.Printf("ResponseVclaim: Encrypted string length: %d", len(encrypted))
|
||||||
|
|
||||||
// Pad the base64 string if needed
|
// Pad the base64 string if needed
|
||||||
if len(encrypted)%4 != 0 {
|
if len(encrypted)%4 != 0 {
|
||||||
@@ -31,81 +34,177 @@ func ResponseVclaim(encrypted string, key string) (string, error) {
|
|||||||
for i := 0; i < padding; i++ {
|
for i := 0; i < padding; i++ {
|
||||||
encrypted += "="
|
encrypted += "="
|
||||||
}
|
}
|
||||||
log.Printf("ResponseVclaim: Padded encrypted string: %s", encrypted)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decode base64
|
||||||
cipherText, err := base64.StdEncoding.DecodeString(encrypted)
|
cipherText, err := base64.StdEncoding.DecodeString(encrypted)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("ResponseVclaim: Failed to decode base64: %v", err)
|
log.Printf("ResponseVclaim: Failed to decode base64: %v", err)
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
log.Printf("ResponseVclaim: Base64 decoded successfully, length: %d", len(cipherText))
|
|
||||||
|
|
||||||
hash := sha256.Sum256([]byte(key))
|
|
||||||
|
|
||||||
block, err := aes.NewCipher(hash[:])
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("ResponseVclaim: Failed to create AES cipher: %v", err)
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(cipherText) < aes.BlockSize {
|
if len(cipherText) < aes.BlockSize {
|
||||||
log.Println("ResponseVclaim: CipherText too short")
|
|
||||||
return "", errors.New("cipherText too short")
|
return "", errors.New("cipherText too short")
|
||||||
}
|
}
|
||||||
|
|
||||||
iv := hash[:aes.BlockSize]
|
// Create AES cipher
|
||||||
|
hash := sha256.Sum256([]byte(key))
|
||||||
|
block, err := aes.NewCipher(hash[:])
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try both IV methods
|
||||||
|
// Method 1: IV from hash (current approach)
|
||||||
|
if result, err := tryDecryptWithHashIV(cipherText, block, hash[:aes.BlockSize]); err == nil {
|
||||||
|
log.Printf("ResponseVclaim: Success with hash IV method")
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method 2: IV from cipherText (standard approach)
|
||||||
|
if result, err := tryDecryptWithCipherIV(cipherText, block); err == nil {
|
||||||
|
log.Printf("ResponseVclaim: Success with cipher IV method")
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", errors.New("all decryption methods failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
func tryDecryptWithHashIV(cipherText []byte, block cipher.Block, iv []byte) (string, error) {
|
||||||
if len(cipherText)%aes.BlockSize != 0 {
|
if len(cipherText)%aes.BlockSize != 0 {
|
||||||
log.Println("ResponseVclaim: CipherText not multiple of block size")
|
|
||||||
return "", errors.New("cipherText is not a multiple of the block size")
|
return "", errors.New("cipherText is not a multiple of the block size")
|
||||||
}
|
}
|
||||||
|
|
||||||
mode := cipher.NewCBCDecrypter(block, iv)
|
mode := cipher.NewCBCDecrypter(block, iv)
|
||||||
mode.CryptBlocks(cipherText, cipherText)
|
decrypted := make([]byte, len(cipherText))
|
||||||
log.Println("ResponseVclaim: AES decryption completed")
|
mode.CryptBlocks(decrypted, cipherText)
|
||||||
|
|
||||||
// cipherText, _ = pkcs7.Unpad(cipherText, aes.BlockSize)
|
// Remove PKCS7 padding
|
||||||
cipherText = helper.RemovePKCS7Padding(cipherText)
|
decrypted = helper.RemovePKCS7Padding(decrypted)
|
||||||
log.Printf("ResponseVclaim: PKCS7 padding removed, length: %d", len(cipherText))
|
log.Printf("tryDecryptWithHashIV: Decryption completed, length: %d", len(decrypted))
|
||||||
|
|
||||||
var data string
|
return tryAllDecompressionMethods(decrypted)
|
||||||
|
}
|
||||||
|
|
||||||
// Try gzip decompression first
|
func tryDecryptWithCipherIV(cipherText []byte, block cipher.Block) (string, error) {
|
||||||
reader, err := gzip.NewReader(bytes.NewReader(cipherText))
|
if len(cipherText) < aes.BlockSize {
|
||||||
if err != nil {
|
return "", errors.New("cipherText too short for IV extraction")
|
||||||
log.Printf("ResponseVclaim: Gzip decompression failed: %v, trying LZ-string decompression", err)
|
}
|
||||||
// Try lz-string decompression using helper function
|
|
||||||
data, err := helper.StringDecrypt(key, string(cipherText))
|
// Extract IV from first block
|
||||||
if err != nil || len(data) == 0 {
|
iv := cipherText[:aes.BlockSize]
|
||||||
log.Printf("ResponseVclaim: Helper StringDecrypt failed or empty: %v, trying without decompression", err)
|
cipherData := cipherText[aes.BlockSize:]
|
||||||
// Try without decompression
|
|
||||||
data = string(cipherText)
|
if len(cipherData)%aes.BlockSize != 0 {
|
||||||
log.Printf("ResponseVclaim: Using decrypted data without decompression, data length: %d", len(data))
|
return "", errors.New("cipher data is not a multiple of the block size")
|
||||||
} else {
|
}
|
||||||
log.Printf("ResponseVclaim: Helper StringDecrypt successful, data length: %d, data: %s", len(data), data[:min(100, len(data))])
|
|
||||||
|
mode := cipher.NewCBCDecrypter(block, iv)
|
||||||
|
decrypted := make([]byte, len(cipherData))
|
||||||
|
mode.CryptBlocks(decrypted, cipherData)
|
||||||
|
|
||||||
|
// Remove PKCS7 padding
|
||||||
|
decrypted = helper.RemovePKCS7Padding(decrypted)
|
||||||
|
log.Printf("tryDecryptWithCipherIV: Decryption completed, length: %d", len(decrypted))
|
||||||
|
|
||||||
|
return tryAllDecompressionMethods(decrypted)
|
||||||
|
}
|
||||||
|
|
||||||
|
func tryAllDecompressionMethods(data []byte) (string, error) {
|
||||||
|
log.Printf("tryAllDecompressionMethods: Attempting decompression, data length: %d", len(data))
|
||||||
|
|
||||||
|
// Method 1: Check if it's already valid JSON
|
||||||
|
if isValidJSON(data) {
|
||||||
|
log.Println("tryAllDecompressionMethods: Data is valid JSON, returning as-is")
|
||||||
|
return string(data), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method 2: Try gzip decompression
|
||||||
|
if result, err := tryGzipDecompression(data); err == nil && len(result) > 0 {
|
||||||
|
log.Println("tryAllDecompressionMethods: Gzip decompression successful")
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method 3: Try LZ-string decompression methods
|
||||||
|
if result, err := tryLZStringMethods(data); err == nil && len(result) > 0 {
|
||||||
|
log.Println("tryAllDecompressionMethods: LZ-string decompression successful")
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method 4: Return as plain text
|
||||||
|
result := string(data)
|
||||||
|
if len(result) > 0 {
|
||||||
|
log.Printf("tryAllDecompressionMethods: Using decrypted data as plain text, length: %d", len(result))
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", errors.New("all decompression methods failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
func isValidJSON(data []byte) bool {
|
||||||
|
if len(data) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
firstChar := data[0]
|
||||||
|
return firstChar == '{' || firstChar == '['
|
||||||
|
}
|
||||||
|
|
||||||
|
func tryGzipDecompression(data []byte) (string, error) {
|
||||||
|
reader, err := gzip.NewReader(bytes.NewReader(data))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
defer reader.Close()
|
defer reader.Close()
|
||||||
|
|
||||||
decompressed, err := io.ReadAll(reader)
|
decompressed, err := io.ReadAll(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("ResponseVclaim: Failed to read gzip decompressed data: %v, trying LZ-string decompression", err)
|
return "", err
|
||||||
// Try lz-string decompression using helper function
|
|
||||||
data, err := helper.StringDecrypt(key, string(cipherText))
|
|
||||||
if err != nil || len(data) == 0 {
|
|
||||||
log.Printf("ResponseVclaim: Helper StringDecrypt failed or empty: %v, using data without decompression", err)
|
|
||||||
data = string(cipherText)
|
|
||||||
log.Printf("ResponseVclaim: Using decrypted data without decompression, data length: %d", len(data))
|
|
||||||
} else {
|
|
||||||
log.Printf("ResponseVclaim: Helper StringDecrypt successful, data length: %d", len(data))
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
data = string(decompressed)
|
return string(decompressed), nil
|
||||||
log.Printf("ResponseVclaim: Gzip decompression successful, data length: %d", len(data))
|
}
|
||||||
|
|
||||||
|
func tryLZStringMethods(data []byte) (string, error) {
|
||||||
|
dataStr := string(data)
|
||||||
|
|
||||||
|
// Method 1: DecompressFromEncodedURIComponent
|
||||||
|
if result, err := lzstring.DecompressFromEncodedURIComponent(dataStr); err == nil && len(result) > 0 {
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method 2: DecompressFromBase64
|
||||||
|
if result, err := lzstring.DecompressFromBase64(dataStr); err == nil && len(result) > 0 {
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method 3: DecompressFromUTF16 (with proper conversion)
|
||||||
|
if utf16Data, err := stringToUTF16(dataStr); err == nil {
|
||||||
|
if result, err := lzstring.DecompressFromUTF16(utf16Data); err == nil && len(result) > 0 {
|
||||||
|
return result, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("ResponseVclaim: Final data length: %d, data: %s", len(data), data[:min(100, len(data))])
|
// Method 4: Try with base64 decoding first
|
||||||
log.Println("ResponseVclaim: Decryption process completed successfully")
|
if decoded, err := base64.StdEncoding.DecodeString(dataStr); err == nil {
|
||||||
return data, nil
|
if result, err := lzstring.DecompressFromEncodedURIComponent(string(decoded)); err == nil && len(result) > 0 {
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", errors.New("all LZ-string methods failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// stringToUTF16 converts string to []uint16 for UTF16 decompression
|
||||||
|
func stringToUTF16(s string) ([]uint16, error) {
|
||||||
|
if len(s) == 0 {
|
||||||
|
return nil, errors.New("empty string")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert string to runes first
|
||||||
|
runes := []rune(s)
|
||||||
|
|
||||||
|
// Convert runes to UTF16
|
||||||
|
utf16Data := utf16.Encode(runes)
|
||||||
|
|
||||||
|
return utf16Data, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import (
|
|||||||
|
|
||||||
"github.com/mashingan/smapping"
|
"github.com/mashingan/smapping"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/tidwall/gjson"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// VClaimService interface for VClaim operations
|
// VClaimService interface for VClaim operations
|
||||||
@@ -139,122 +138,62 @@ func (s *Service) prepareRequest(ctx context.Context, method, endpoint string, b
|
|||||||
func (s *Service) processResponse(res *http.Response) (*ResponDTOVclaim, error) {
|
func (s *Service) processResponse(res *http.Response) (*ResponDTOVclaim, error) {
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
|
|
||||||
log.Info().
|
|
||||||
Int("status_code", res.StatusCode).
|
|
||||||
Str("status", res.Status).
|
|
||||||
Msg("Processing HTTP response")
|
|
||||||
|
|
||||||
body, err := io.ReadAll(res.Body)
|
body, err := io.ReadAll(res.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().
|
|
||||||
Err(err).
|
|
||||||
Int("status_code", res.StatusCode).
|
|
||||||
Msg("Failed to read response body")
|
|
||||||
return nil, fmt.Errorf("failed to read response body: %w", err)
|
return nil, fmt.Errorf("failed to read response body: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log response body for debugging (truncate if too long)
|
|
||||||
bodyStr := string(body)
|
|
||||||
if len(bodyStr) > 1000 {
|
|
||||||
bodyStr = bodyStr[:1000] + "...(truncated)"
|
|
||||||
}
|
|
||||||
log.Debug().
|
|
||||||
Int("status_code", res.StatusCode).
|
|
||||||
Str("response_body", bodyStr).
|
|
||||||
Msg("Raw response received")
|
|
||||||
|
|
||||||
// Check HTTP status
|
|
||||||
if res.StatusCode >= 400 {
|
if res.StatusCode >= 400 {
|
||||||
log.Error().
|
|
||||||
Int("status_code", res.StatusCode).
|
|
||||||
Str("response_body", bodyStr).
|
|
||||||
Msg("HTTP error response")
|
|
||||||
return nil, fmt.Errorf("HTTP error: %d - %s", res.StatusCode, string(body))
|
return nil, fmt.Errorf("HTTP error: %d - %s", res.StatusCode, string(body))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse raw response
|
// Parse raw response
|
||||||
var respMentah ResponMentahDTOVclaim
|
var respMentah ResponMentahDTOVclaim
|
||||||
if err := json.Unmarshal(body, &respMentah); err != nil {
|
if err := json.Unmarshal(body, &respMentah); err != nil {
|
||||||
log.Error().
|
|
||||||
Err(err).
|
|
||||||
Int("status_code", res.StatusCode).
|
|
||||||
Msg("Failed to unmarshal raw response")
|
|
||||||
return nil, fmt.Errorf("failed to unmarshal raw response: %w", err)
|
return nil, fmt.Errorf("failed to unmarshal raw response: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log metadata
|
|
||||||
log.Info().
|
|
||||||
Str("meta_code", respMentah.MetaData.Code).
|
|
||||||
Str("meta_message", respMentah.MetaData.Message).
|
|
||||||
Msg("Response metadata")
|
|
||||||
|
|
||||||
// Create final response
|
// Create final response
|
||||||
finalResp := &ResponDTOVclaim{
|
finalResp := &ResponDTOVclaim{
|
||||||
MetaData: respMentah.MetaData,
|
MetaData: respMentah.MetaData,
|
||||||
}
|
}
|
||||||
|
|
||||||
// If response is empty, return as is
|
// Check if response needs decryption
|
||||||
if respMentah.Response == "" {
|
if respMentah.Response == "" {
|
||||||
log.Debug().Msg("Empty response received, returning metadata only")
|
|
||||||
return finalResp, nil
|
return finalResp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to unmarshal response as JSON first (in case it's not encrypted)
|
// Try to parse as JSON first (unencrypted response)
|
||||||
var tempResp interface{}
|
var tempResp interface{}
|
||||||
if json.Unmarshal([]byte(respMentah.Response), &tempResp) == nil {
|
if json.Unmarshal([]byte(respMentah.Response), &tempResp) == nil {
|
||||||
log.Debug().Msg("Response is valid JSON, not encrypted")
|
|
||||||
finalResp.Response = tempResp
|
finalResp.Response = tempResp
|
||||||
} else {
|
return finalResp, nil
|
||||||
log.Debug().Msg("Response is not valid JSON, trying to decrypt")
|
}
|
||||||
|
|
||||||
// Decrypt response
|
// Decrypt response
|
||||||
consID, secretKey, _, tstamp, _ := s.config.SetHeader()
|
consID, secretKey, _, tstamp, _ := s.config.SetHeader()
|
||||||
respDecrypt, err := ResponseVclaim(respMentah.Response, consID+secretKey+tstamp)
|
decryptionKey := consID + secretKey + tstamp
|
||||||
|
|
||||||
|
log.Debug().
|
||||||
|
Str("consID", consID).
|
||||||
|
Str("tstamp", tstamp).
|
||||||
|
Int("key_length", len(decryptionKey)).
|
||||||
|
Msg("Decryption key components")
|
||||||
|
|
||||||
|
respDecrypt, err := ResponseVclaim(respMentah.Response, decryptionKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().
|
log.Error().Err(err).Msg("Failed to decrypt response")
|
||||||
Err(err).
|
|
||||||
Str("meta_code", respMentah.MetaData.Code).
|
|
||||||
Msg("Failed to decrypt response")
|
|
||||||
return nil, fmt.Errorf("failed to decrypt response: %w", err)
|
return nil, fmt.Errorf("failed to decrypt response: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug().
|
// Try to unmarshal decrypted response as JSON
|
||||||
Str("encrypted_length", fmt.Sprintf("%d bytes", len(respMentah.Response))).
|
|
||||||
Str("decrypted_length", fmt.Sprintf("%d bytes", len(respDecrypt))).
|
|
||||||
Msg("Response decrypted successfully")
|
|
||||||
|
|
||||||
log.Debug().
|
|
||||||
Str("decrypted_data", respDecrypt).
|
|
||||||
Msg("Decrypted data")
|
|
||||||
|
|
||||||
// Unmarshal decrypted response
|
|
||||||
if respDecrypt != "" {
|
if respDecrypt != "" {
|
||||||
if err := json.Unmarshal([]byte(respDecrypt), &finalResp.Response); err != nil {
|
if err := json.Unmarshal([]byte(respDecrypt), &finalResp.Response); err != nil {
|
||||||
// If JSON unmarshal fails, store as string
|
// If JSON unmarshal fails, store as string
|
||||||
log.Warn().
|
log.Warn().Err(err).Msg("Failed to unmarshal decrypted response, storing as string")
|
||||||
Err(err).
|
|
||||||
Msg("Failed to unmarshal decrypted response, storing as string")
|
|
||||||
finalResp.Response = respDecrypt
|
finalResp.Response = respDecrypt
|
||||||
} else {
|
|
||||||
log.Debug().Msg("Decrypted response unmarshaled successfully")
|
|
||||||
|
|
||||||
// Use gjson to extract and log some metadata from the response if it's JSON
|
|
||||||
if jsonBytes, err := json.Marshal(finalResp.Response); err == nil {
|
|
||||||
jsonStr := string(jsonBytes)
|
|
||||||
// Extract some common fields using gjson
|
|
||||||
if metaCode := gjson.Get(jsonStr, "metaData.code"); metaCode.Exists() {
|
|
||||||
log.Info().
|
|
||||||
Str("response_meta_code", metaCode.String()).
|
|
||||||
Msg("Final response metadata")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info().
|
|
||||||
Str("meta_code", finalResp.MetaData.Code).
|
|
||||||
Str("meta_message", finalResp.MetaData.Message).
|
|
||||||
Msg("Response processing completed")
|
|
||||||
|
|
||||||
return finalResp, nil
|
return finalResp, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user