81 lines
3.0 KiB
Go
81 lines
3.0 KiB
Go
package kyc
|
|
|
|
import (
|
|
"context"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"service/internal/infrastructure/config"
|
|
"service/internal/interfaces/satusehat"
|
|
"service/pkg/crypto"
|
|
"service/pkg/errors"
|
|
"service/pkg/logger"
|
|
)
|
|
|
|
type Service interface {
|
|
GenerateURL(ctx context.Context, req GenerateURLRequest) (*satusehat.FHIRResponse, error)
|
|
HandleCallback(ctx context.Context, encryptedPayload string, token string) error
|
|
}
|
|
|
|
type service struct {
|
|
repo Repository
|
|
cfg config.SatuSehatConfig
|
|
}
|
|
|
|
func NewService(repo Repository, cfg config.SatuSehatConfig) Service {
|
|
return &service{repo: repo, cfg: cfg}
|
|
}
|
|
|
|
func (s *service) GenerateURL(ctx context.Context, req GenerateURLRequest) (*satusehat.FHIRResponse, error) {
|
|
// Gunakan public key statis dari konfigurasi (disimpan dalam format Base64 di .env)
|
|
pubKeyBytes, err := base64.StdEncoding.DecodeString(s.cfg.KYCPublicKeyB64)
|
|
if err != nil {
|
|
return nil, errors.InternalError().Message("Gagal mendecode Public Key dari konfigurasi").Cause(err).Build()
|
|
}
|
|
req.PublicKey = string(pubKeyBytes)
|
|
|
|
// Decode private key untuk mendekripsi balasan generate URL dari Kemenkes
|
|
privKeyBytes, err := base64.StdEncoding.DecodeString(s.cfg.KYCPrivateKeyB64)
|
|
if err != nil {
|
|
return nil, errors.InternalError().Message("Gagal mendecode Private Key dari konfigurasi").Cause(err).Build()
|
|
}
|
|
privKeyPEM := string(privKeyBytes)
|
|
|
|
// Lempar privKeyPEM ke repo agar Kemenkes response dapat didekripsi
|
|
return s.repo.GenerateURL(ctx, req, privKeyPEM)
|
|
}
|
|
|
|
func (s *service) HandleCallback(ctx context.Context, encryptedPayload string, token string) error {
|
|
// Validasi Security Token dari Kemenkes
|
|
expectedToken := s.cfg.WebhookSecret
|
|
if expectedToken == "" {
|
|
logger.Default().Warn("SATUSEHAT_WEBHOOK_SECRET belum dikonfigurasi. Validasi token webhook dilewati.")
|
|
} else if token != expectedToken {
|
|
logger.Default().Warn("Webhook KYC gagal divalidasi: Token tidak cocok", logger.String("received_token", token))
|
|
return errors.UnauthorizedError().Message("Invalid security webhook token").Build()
|
|
}
|
|
|
|
// 1. Dapatkan Private Key statis Anda dari config/env var
|
|
privKeyBytes, err := base64.StdEncoding.DecodeString(s.cfg.KYCPrivateKeyB64)
|
|
if err != nil {
|
|
return errors.InternalError().Message("Gagal mendecode Private Key dari konfigurasi").Cause(err).Build()
|
|
}
|
|
privKeyPEM := string(privKeyBytes)
|
|
|
|
// 2. Dekripsi payload yang masuk
|
|
decryptedBytes, err := crypto.DecryptSatuSehatPayload(encryptedPayload, privKeyPEM)
|
|
if err != nil {
|
|
return errors.InternalError().Message("Gagal mendekripsi payload webhook dari SatuSehat").Cause(err).Build()
|
|
}
|
|
|
|
// 3. Unmarshal ke bentuk Struct
|
|
var payload CallbackRequest
|
|
if err := json.Unmarshal(decryptedBytes, &payload); err != nil {
|
|
return errors.InternalError().Message("Gagal memparsing JSON hasil dekripsi").Cause(err).Build()
|
|
}
|
|
|
|
// TODO: Tambahkan logika update ke database lokal (misal: tabel user/agent) berdasarkan hasil KYC.
|
|
// Saat ini, kita log payload yang diterima dari Kemenkes.
|
|
logger.Default().Info("Menerima Webhook KYC dari SatuSehat", logger.Any("payload", payload))
|
|
return nil
|
|
}
|