perbaikan decript
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
// Service: VClaim (vclaim)
|
// Service: VClaim (vclaim)
|
||||||
// Description: BPJS VClaim service for eligibility and SEP management
|
// Description: BPJS VClaim service for eligibility and SEP management
|
||||||
|
|
||||||
@@ -6,14 +5,14 @@ package peserta
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"strings"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"api-service/internal/config"
|
"api-service/internal/config"
|
||||||
"api-service/internal/models"
|
"api-service/internal/models"
|
||||||
"api-service/internal/models/vclaim/peserta"
|
services "api-service/internal/services/bpjs"
|
||||||
"api-service/internal/services/bpjs"
|
|
||||||
"api-service/pkg/logger"
|
"api-service/pkg/logger"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@@ -21,6 +20,62 @@ import (
|
|||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// PesertaData represents peserta information from BPJS
|
||||||
|
type PesertaData struct {
|
||||||
|
NoKartu string `json:"noKartu"`
|
||||||
|
NIK string `json:"nik"`
|
||||||
|
Nama string `json:"nama"`
|
||||||
|
Pisa string `json:"pisa"`
|
||||||
|
Sex string `json:"sex"`
|
||||||
|
TanggalLahir string `json:"tglLahir"`
|
||||||
|
TglCetakKartu string `json:"tglCetakKartu"`
|
||||||
|
TglTAT string `json:"tglTAT"`
|
||||||
|
TglTMT string `json:"tglTMT"`
|
||||||
|
StatusPeserta struct {
|
||||||
|
Kode string `json:"kode"`
|
||||||
|
Keterangan string `json:"keterangan"`
|
||||||
|
} `json:"statusPeserta"`
|
||||||
|
ProvUmum struct {
|
||||||
|
KdProvider string `json:"kdProvider"`
|
||||||
|
NmProvider string `json:"nmProvider"`
|
||||||
|
} `json:"provUmum"`
|
||||||
|
JenisPeserta struct {
|
||||||
|
Kode string `json:"kode"`
|
||||||
|
Keterangan string `json:"keterangan"`
|
||||||
|
} `json:"jenisPeserta"`
|
||||||
|
HakKelas struct {
|
||||||
|
Kode string `json:"kode"`
|
||||||
|
Keterangan string `json:"keterangan"`
|
||||||
|
} `json:"hakKelas"`
|
||||||
|
Umur struct {
|
||||||
|
UmurSekarang string `json:"umurSekarang"`
|
||||||
|
UmurSaatPelayanan string `json:"umurSaatPelayanan"`
|
||||||
|
} `json:"umur"`
|
||||||
|
Informasi struct {
|
||||||
|
Dinsos interface{} `json:"dinsos"`
|
||||||
|
ProlanisPRB string `json:"prolanisPRB"`
|
||||||
|
NoSKTM interface{} `json:"noSKTM"`
|
||||||
|
ESEP interface{} `json:"eSEP"`
|
||||||
|
} `json:"informasi"`
|
||||||
|
Cob struct {
|
||||||
|
NoAsuransi interface{} `json:"noAsuransi"`
|
||||||
|
NmAsuransi interface{} `json:"nmAsuransi"`
|
||||||
|
TglTMT interface{} `json:"tglTMT"`
|
||||||
|
TglTAT interface{} `json:"tglTAT"`
|
||||||
|
} `json:"cob"`
|
||||||
|
MR struct {
|
||||||
|
NoMR string `json:"noMR"`
|
||||||
|
NoTelepon string `json:"noTelepon"`
|
||||||
|
} `json:"mr,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PesertaResponse represents peserta API response
|
||||||
|
type PesertaResponse struct {
|
||||||
|
models.BaseResponse
|
||||||
|
Data *PesertaData `json:"data,omitempty"`
|
||||||
|
MetaData interface{} `json:"metaData,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// VClaimHandler handles VClaim BPJS services
|
// VClaimHandler handles VClaim BPJS services
|
||||||
type VClaimHandler struct {
|
type VClaimHandler struct {
|
||||||
service services.VClaimService
|
service services.VClaimService
|
||||||
@@ -46,7 +101,6 @@ func NewVClaimHandler(cfg VClaimHandlerConfig) *VClaimHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// GetPesertaBynokartu godoc
|
// GetPesertaBynokartu godoc
|
||||||
// @Summary Get PesertaBynokartu data
|
// @Summary Get PesertaBynokartu data
|
||||||
// @Description Get participant eligibility information by card number
|
// @Description Get participant eligibility information by card number
|
||||||
@@ -73,19 +127,16 @@ func (h *VClaimHandler) GetPesertaBynokartu(c *gin.Context) {
|
|||||||
c.Header("X-Request-ID", requestID)
|
c.Header("X-Request-ID", requestID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
h.logger.Info("Processing GetPesertaBynokartu request", map[string]interface{}{
|
h.logger.Info("Processing GetPesertaBynokartu request", map[string]interface{}{
|
||||||
"request_id": requestID,
|
"request_id": requestID,
|
||||||
"endpoint": "/peserta/:nokartu",
|
|
||||||
|
|
||||||
"nokartu": c.Param("nokartu"),
|
"nokartu": c.Param("nokartu"),
|
||||||
|
"tglsep": c.Param("tglsep"),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
// Extract path parameters
|
// Extract path parameters
|
||||||
|
|
||||||
nokartu := c.Param("nokartu")
|
nokartu := c.Param("nokartu")
|
||||||
|
tglsep := c.Param("tglsep")
|
||||||
if nokartu == "" {
|
if nokartu == "" {
|
||||||
|
|
||||||
h.logger.Error("Missing required parameter nokartu", map[string]interface{}{
|
h.logger.Error("Missing required parameter nokartu", map[string]interface{}{
|
||||||
@@ -100,18 +151,16 @@ func (h *VClaimHandler) GetPesertaBynokartu(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Call service method
|
// Call service method
|
||||||
var response peserta.PesertaResponse
|
var response PesertaResponse
|
||||||
|
|
||||||
endpoint := "/peserta/:nokartu"
|
endpoint := "/Peserta/nokartu/:nokartu/tglSEP/:tglsep"
|
||||||
|
|
||||||
endpoint = strings.Replace(endpoint, ":nokartu", nokartu, 1)
|
endpoint = strings.Replace(endpoint, ":nokartu", nokartu, 1)
|
||||||
|
endpoint = strings.Replace(endpoint, ":tglsep", tglsep, 1)
|
||||||
|
|
||||||
err := h.service.Get(ctx, endpoint, &response)
|
resp, err := h.service.GetRawResponse(ctx, endpoint)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
h.logger.Error("Failed to get PesertaBynokartu", map[string]interface{}{
|
h.logger.Error("Failed to get PesertaBynokartu", map[string]interface{}{
|
||||||
"error": err.Error(),
|
"error": err.Error(),
|
||||||
"request_id": requestID,
|
"request_id": requestID,
|
||||||
@@ -125,20 +174,41 @@ func (h *VClaimHandler) GetPesertaBynokartu(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Map the raw response
|
||||||
|
response.MetaData = resp.MetaData
|
||||||
|
if resp.Response != nil {
|
||||||
|
response.Data = &PesertaData{}
|
||||||
|
if respStr, ok := resp.Response.(string); ok {
|
||||||
|
// Decrypt the response string
|
||||||
|
consID, secretKey, _, tstamp, _ := h.config.SetHeader()
|
||||||
|
decryptedResp, err := services.ResponseVclaim(respStr, consID+secretKey+tstamp)
|
||||||
|
if err != nil {
|
||||||
|
h.logger.Error("Failed to decrypt response", map[string]interface{}{
|
||||||
|
"error": err.Error(),
|
||||||
|
"request_id": requestID,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
json.Unmarshal([]byte(decryptedResp), response.Data)
|
||||||
|
}
|
||||||
|
} else if respMap, ok := resp.Response.(map[string]interface{}); ok {
|
||||||
|
// Response is already unmarshaled JSON
|
||||||
|
if pesertaMap, exists := respMap["peserta"]; exists {
|
||||||
|
pesertaBytes, _ := json.Marshal(pesertaMap)
|
||||||
|
json.Unmarshal(pesertaBytes, response.Data)
|
||||||
|
} else {
|
||||||
|
// Try to unmarshal the whole response
|
||||||
|
respBytes, _ := json.Marshal(resp.Response)
|
||||||
|
json.Unmarshal(respBytes, response.Data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure response has proper fields
|
// Ensure response has proper fields
|
||||||
response.Status = "success"
|
response.Status = "success"
|
||||||
response.RequestID = requestID
|
response.RequestID = requestID
|
||||||
c.JSON(http.StatusOK, response)
|
c.JSON(http.StatusOK, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// GetPesertaBynik godoc
|
// GetPesertaBynik godoc
|
||||||
// @Summary Get PesertaBynik data
|
// @Summary Get PesertaBynik data
|
||||||
// @Description Get participant eligibility information by NIK
|
// @Description Get participant eligibility information by NIK
|
||||||
@@ -165,16 +235,13 @@ func (h *VClaimHandler) GetPesertaBynik(c *gin.Context) {
|
|||||||
c.Header("X-Request-ID", requestID)
|
c.Header("X-Request-ID", requestID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
h.logger.Info("Processing GetPesertaBynik request", map[string]interface{}{
|
h.logger.Info("Processing GetPesertaBynik request", map[string]interface{}{
|
||||||
"request_id": requestID,
|
"request_id": requestID,
|
||||||
"endpoint": "/peserta/nik/:nik",
|
"endpoint": "/peserta/nik/:nik",
|
||||||
|
|
||||||
"nik": c.Param("nik"),
|
"nik": c.Param("nik"),
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
// Extract path parameters
|
// Extract path parameters
|
||||||
|
|
||||||
nik := c.Param("nik")
|
nik := c.Param("nik")
|
||||||
@@ -192,18 +259,15 @@ func (h *VClaimHandler) GetPesertaBynik(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Call service method
|
// Call service method
|
||||||
var response peserta.PesertaResponse
|
var response PesertaResponse
|
||||||
|
|
||||||
endpoint := "/peserta/nik/:nik"
|
endpoint := "/peserta/nik/:nik"
|
||||||
|
|
||||||
endpoint = strings.Replace(endpoint, ":nik", nik, 1)
|
endpoint = strings.Replace(endpoint, ":nik", nik, 1)
|
||||||
|
|
||||||
err := h.service.Get(ctx, endpoint, &response)
|
resp, err := h.service.GetRawResponse(ctx, endpoint)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
h.logger.Error("Failed to get PesertaBynik", map[string]interface{}{
|
h.logger.Error("Failed to get PesertaBynik", map[string]interface{}{
|
||||||
"error": err.Error(),
|
"error": err.Error(),
|
||||||
"request_id": requestID,
|
"request_id": requestID,
|
||||||
@@ -217,16 +281,37 @@ func (h *VClaimHandler) GetPesertaBynik(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Map the raw response
|
||||||
|
response.MetaData = resp.MetaData
|
||||||
|
if resp.Response != nil {
|
||||||
|
response.Data = &PesertaData{}
|
||||||
|
if respStr, ok := resp.Response.(string); ok {
|
||||||
|
// Decrypt the response string
|
||||||
|
consID, secretKey, _, tstamp, _ := h.config.SetHeader()
|
||||||
|
decryptedResp, err := services.ResponseVclaim(respStr, consID+secretKey+tstamp)
|
||||||
|
if err != nil {
|
||||||
|
h.logger.Error("Failed to decrypt response", map[string]interface{}{
|
||||||
|
"error": err.Error(),
|
||||||
|
"request_id": requestID,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
json.Unmarshal([]byte(decryptedResp), response.Data)
|
||||||
|
}
|
||||||
|
} else if respMap, ok := resp.Response.(map[string]interface{}); ok {
|
||||||
|
// Response is already unmarshaled JSON
|
||||||
|
if pesertaMap, exists := respMap["peserta"]; exists {
|
||||||
|
pesertaBytes, _ := json.Marshal(pesertaMap)
|
||||||
|
json.Unmarshal(pesertaBytes, response.Data)
|
||||||
|
} else {
|
||||||
|
// Try to unmarshal the whole response
|
||||||
|
respBytes, _ := json.Marshal(resp.Response)
|
||||||
|
json.Unmarshal(respBytes, response.Data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure response has proper fields
|
// Ensure response has proper fields
|
||||||
response.Status = "success"
|
response.Status = "success"
|
||||||
response.RequestID = requestID
|
response.RequestID = requestID
|
||||||
c.JSON(http.StatusOK, response)
|
c.JSON(http.StatusOK, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -21,27 +21,44 @@ type PesertaData struct {
|
|||||||
Pisa string `json:"pisa"`
|
Pisa string `json:"pisa"`
|
||||||
Sex string `json:"sex"`
|
Sex string `json:"sex"`
|
||||||
TanggalLahir string `json:"tglLahir"`
|
TanggalLahir string `json:"tglLahir"`
|
||||||
TelephoneMsisdn string `json:"tglTAT"`
|
TglCetakKartu string `json:"tglCetakKartu"`
|
||||||
TelephoneAsat string `json:"tglTMT"`
|
TglTAT string `json:"tglTAT"`
|
||||||
KodeCabang string `json:"kdCabang"`
|
TglTMT string `json:"tglTMT"`
|
||||||
NamaCabang string `json:"nmCabang"`
|
StatusPeserta struct {
|
||||||
KodeJenisPeserta string `json:"kdJnsPst"`
|
Kode string `json:"kode"`
|
||||||
NamaJenisPeserta string `json:"nmJnsPst"`
|
Keterangan string `json:"keterangan"`
|
||||||
KelasRawat string `json:"klsRawat"`
|
} `json:"statusPeserta"`
|
||||||
Status string `json:"statusPeserta"`
|
ProvUmum struct {
|
||||||
Aktif string `json:"aktif"`
|
KdProvider string `json:"kdProvider"`
|
||||||
KeteranganAktif string `json:"ketAktif"`
|
NmProvider string `json:"nmProvider"`
|
||||||
NoSKTM string `json:"noSKTM,omitempty"`
|
} `json:"provUmum"`
|
||||||
NoKTP string `json:"noKtp"`
|
JenisPeserta struct {
|
||||||
Asuransi string `json:"asuransi,omitempty"`
|
Kode string `json:"kode"`
|
||||||
CoB string `json:"cob,omitempty"`
|
Keterangan string `json:"keterangan"`
|
||||||
TunggakanIuran string `json:"tglTunggak,omitempty"`
|
} `json:"jenisPeserta"`
|
||||||
|
HakKelas struct {
|
||||||
|
Kode string `json:"kode"`
|
||||||
|
Keterangan string `json:"keterangan"`
|
||||||
|
} `json:"hakKelas"`
|
||||||
|
Umur struct {
|
||||||
|
UmurSekarang string `json:"umurSekarang"`
|
||||||
|
UmurSaatPelayanan string `json:"umurSaatPelayanan"`
|
||||||
|
} `json:"umur"`
|
||||||
|
Informasi struct {
|
||||||
|
Dinsos interface{} `json:"dinsos"`
|
||||||
|
ProlanisPRB string `json:"prolanisPRB"`
|
||||||
|
NoSKTM interface{} `json:"noSKTM"`
|
||||||
|
ESEP interface{} `json:"eSEP"`
|
||||||
|
} `json:"informasi"`
|
||||||
|
Cob struct {
|
||||||
|
NoAsuransi interface{} `json:"noAsuransi"`
|
||||||
|
NmAsuransi interface{} `json:"nmAsuransi"`
|
||||||
|
TglTMT interface{} `json:"tglTMT"`
|
||||||
|
TglTAT interface{} `json:"tglTAT"`
|
||||||
|
} `json:"cob"`
|
||||||
MR struct {
|
MR struct {
|
||||||
NoMR string `json:"noMR"`
|
NoMR string `json:"noMR"`
|
||||||
NamaMR string `json:"nmMR"`
|
NoTelepon string `json:"noTelepon"`
|
||||||
Sex string `json:"sex"`
|
|
||||||
TglLahir string `json:"tglLahir"`
|
|
||||||
TglMeninggal string `json:"tglMeninggal,omitempty"`
|
|
||||||
} `json:"mr,omitempty"`
|
} `json:"mr,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ func RegisterRoutes(cfg *config.Config) *gin.Engine {
|
|||||||
Validator: nil,
|
Validator: nil,
|
||||||
})
|
})
|
||||||
pesertaGroup := v1.Group("/peserta")
|
pesertaGroup := v1.Group("/peserta")
|
||||||
pesertaGroup.GET("/peserta/:nokartu", pesertaHandler.GetPesertaBynokartu)
|
pesertaGroup.GET("/peserta/:nokartu/tglSEP/:tglsep", pesertaHandler.GetPesertaBynokartu)
|
||||||
pesertaGroup.GET("/peserta/nik/:nik", pesertaHandler.GetPesertaBynik)
|
pesertaGroup.GET("/peserta/nik/:nik", pesertaHandler.GetPesertaBynik)
|
||||||
|
|
||||||
// Sep routes
|
// Sep routes
|
||||||
|
|||||||
@@ -2,49 +2,110 @@ package services
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
helper "api-service/internal/helpers/bpjs"
|
helper "api-service/internal/helpers/bpjs"
|
||||||
|
"bytes"
|
||||||
|
"compress/gzip"
|
||||||
"crypto/aes"
|
"crypto/aes"
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
|
"io"
|
||||||
lzstring "github.com/daku10/go-lz-string"
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func min(a, b int) int {
|
||||||
|
if a < b {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
// 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.Printf("ResponseVclaim: Encrypted string: %s", encrypted)
|
||||||
|
|
||||||
|
// Pad the base64 string if needed
|
||||||
|
if len(encrypted)%4 != 0 {
|
||||||
|
padding := (4 - len(encrypted)%4) % 4
|
||||||
|
for i := 0; i < padding; i++ {
|
||||||
|
encrypted += "="
|
||||||
|
}
|
||||||
|
log.Printf("ResponseVclaim: Padded encrypted string: %s", encrypted)
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
log.Printf("ResponseVclaim: Base64 decoded successfully, length: %d", len(cipherText))
|
||||||
|
|
||||||
hash := sha256.Sum256([]byte(key))
|
hash := sha256.Sum256([]byte(key))
|
||||||
|
|
||||||
block, err := aes.NewCipher(hash[:])
|
block, err := aes.NewCipher(hash[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Printf("ResponseVclaim: Failed to create AES cipher: %v", err)
|
||||||
return "", 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]
|
iv := hash[:aes.BlockSize]
|
||||||
|
|
||||||
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)
|
mode.CryptBlocks(cipherText, cipherText)
|
||||||
|
log.Println("ResponseVclaim: AES decryption completed")
|
||||||
|
|
||||||
// cipherText, _ = pkcs7.Unpad(cipherText, aes.BlockSize)
|
// cipherText, _ = pkcs7.Unpad(cipherText, aes.BlockSize)
|
||||||
cipherText = helper.RemovePKCS7Padding(cipherText)
|
cipherText = helper.RemovePKCS7Padding(cipherText)
|
||||||
data, err := lzstring.DecompressFromEncodedURIComponent(string(cipherText))
|
log.Printf("ResponseVclaim: PKCS7 padding removed, length: %d", len(cipherText))
|
||||||
// data, err := helper.DecompressFromEncodedUriComponent(string(cipherText))
|
|
||||||
|
var data string
|
||||||
|
|
||||||
|
// Try gzip decompression first
|
||||||
|
reader, err := gzip.NewReader(bytes.NewReader(cipherText))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
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))
|
||||||
|
if err != nil || len(data) == 0 {
|
||||||
|
log.Printf("ResponseVclaim: Helper StringDecrypt failed or empty: %v, trying without decompression", err)
|
||||||
|
// Try without decompression
|
||||||
|
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, data: %s", len(data), data[:min(100, len(data))])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
defer reader.Close()
|
||||||
|
decompressed, err := io.ReadAll(reader)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("ResponseVclaim: Failed to read gzip decompressed data: %v, trying LZ-string decompression", 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)
|
||||||
|
log.Printf("ResponseVclaim: Gzip decompression successful, data length: %d", len(data))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Printf("ResponseVclaim: Final data length: %d, data: %s", len(data), data[:min(100, len(data))])
|
||||||
|
log.Println("ResponseVclaim: Decryption process completed successfully")
|
||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"api-service/internal/config"
|
"api-service/internal/config"
|
||||||
|
"api-service/internal/models/vclaim/peserta"
|
||||||
|
|
||||||
"github.com/mashingan/smapping"
|
"github.com/mashingan/smapping"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
@@ -198,6 +199,13 @@ func (s *Service) processResponse(res *http.Response) (*ResponDTOVclaim, error)
|
|||||||
return finalResp, nil
|
return finalResp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try to unmarshal response as JSON first (in case it's not encrypted)
|
||||||
|
var tempResp interface{}
|
||||||
|
if json.Unmarshal([]byte(respMentah.Response), &tempResp) == nil {
|
||||||
|
log.Debug().Msg("Response is valid JSON, not encrypted")
|
||||||
|
finalResp.Response = tempResp
|
||||||
|
} else {
|
||||||
|
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)
|
respDecrypt, err := ResponseVclaim(respMentah.Response, consID+secretKey+tstamp)
|
||||||
@@ -214,6 +222,10 @@ func (s *Service) processResponse(res *http.Response) (*ResponDTOVclaim, error)
|
|||||||
Str("decrypted_length", fmt.Sprintf("%d bytes", len(respDecrypt))).
|
Str("decrypted_length", fmt.Sprintf("%d bytes", len(respDecrypt))).
|
||||||
Msg("Response decrypted successfully")
|
Msg("Response decrypted successfully")
|
||||||
|
|
||||||
|
log.Debug().
|
||||||
|
Str("decrypted_data", respDecrypt).
|
||||||
|
Msg("Decrypted data")
|
||||||
|
|
||||||
// Unmarshal decrypted response
|
// 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 {
|
||||||
@@ -237,6 +249,7 @@ func (s *Service) processResponse(res *http.Response) (*ResponDTOVclaim, error)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
log.Info().
|
log.Info().
|
||||||
Str("meta_code", finalResp.MetaData.Code).
|
Str("meta_code", finalResp.MetaData.Code).
|
||||||
@@ -410,6 +423,20 @@ func mapToResult(resp *ResponDTOVclaim, result interface{}) error {
|
|||||||
return fmt.Errorf("failed to unmarshal to result: %w", err)
|
return fmt.Errorf("failed to unmarshal to result: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle BPJS peserta response structure
|
||||||
|
if pesertaResp, ok := result.(*peserta.PesertaResponse); ok {
|
||||||
|
if resp.Response != nil {
|
||||||
|
if responseMap, ok := resp.Response.(map[string]interface{}); ok {
|
||||||
|
if pesertaMap, ok := responseMap["peserta"]; ok {
|
||||||
|
pesertaBytes, _ := json.Marshal(pesertaMap)
|
||||||
|
var pd peserta.PesertaData
|
||||||
|
json.Unmarshal(pesertaBytes, &pd)
|
||||||
|
pesertaResp.Data = &pd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user