Files

141 lines
3.6 KiB
Go

package verify
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
"time"
"bsm/full/module/base/passport/internal/config"
"bsm/full/module/base/passport/internal/impl"
"bsm/full/module/base/passport/internal/logic/common"
"bsm/full/module/base/passport/internal/models"
pb "bsm/full/module/base/passport/pb"
"git.apinb.com/bsm-sdk/core/errcode"
"git.apinb.com/bsm-sdk/core/printer"
"git.apinb.com/bsm-sdk/core/service"
)
type JumioInitRequest struct {
CustomerInternalReference string `json:"customerInternalReference"`
UserReference string `json:"userReference"`
SuccessURL string `json:"successUrl"`
ErrorURL string `json:"errorUrl"`
CallbackURL string `json:"callbackUrl"`
}
type JumioInitResponse struct {
Timestamp string `json:"timestamp"`
ScanReference string `json:"scanReference"`
ClientRedirectURL string `json:"clientRedirectUrl"`
}
func Request(ctx context.Context, in *pb.VerifyRequest) (reply *pb.StatusReply, err error) {
auth, err := service.ParseMetaCtx(ctx, nil)
if err != nil {
return nil, err
}
var data string
switch strings.ToLower(in.Provider) {
case "jumio":
id := fmt.Sprintf("ID_%d", auth.ID)
resp, err := InitiateJumioScan(id, auth.Identity)
if err != nil {
printer.Error(err.Error())
return nil, errcode.ErrInternal
}
data = resp.ClientRedirectURL
case "local":
if !common.VerifyMapKeys(in.Args, []string{"type", "name", "number", "front", "back"}) {
return nil, errcode.ErrInvalidArgument
}
err = LocalVerify(auth.ID, in.Args)
if err != nil {
printer.Error(err.Error())
return nil, errcode.ErrDB
}
default:
return nil, errcode.ErrNotFound(404, "provider")
}
return &pb.StatusReply{
Details: data,
Timeseq: time.Now().UnixMilli(),
}, nil
}
func LocalVerify(authID uint, args map[string]string) error {
err := impl.DBService.Model(&models.PassportData{}).Where("passport_id = ?", authID).Update("document_verify", 1).Error
if err != nil {
return err
}
err = impl.DBService.Model(&models.PassportVerify{}).Where("passport_id = ?", authID).Updates(map[string]any{
"document_verify_at": time.Now(),
"document_type": args["type"],
"document_name": args["name"],
"document_number": args["number"],
"document_front": args["front"],
"document_back": args["back"],
}).Error
if err != nil {
return err
}
return nil
}
func InitiateJumioScan(internalRef, userRef string) (*JumioInitResponse, error) {
if config.Spec.Kyc == nil {
return nil, fmt.Errorf("kyc config is missing")
}
reqBody := JumioInitRequest{
CustomerInternalReference: internalRef,
UserReference: userRef,
CallbackURL: config.Spec.Kyc.ApiArgs,
}
jsonBody, err := json.Marshal(reqBody)
if err != nil {
return nil, err
}
client := &http.Client{Timeout: 10 * time.Second}
req, err := http.NewRequest(http.MethodPost, config.Spec.Kyc.BaseUrl, bytes.NewBuffer(jsonBody))
if err != nil {
return nil, err
}
req.SetBasicAuth(config.Spec.Kyc.ApiToken, config.Spec.Kyc.ApiSecret)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("User-Agent", "BSM-Passport/1.0")
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("jumio api error: status=%d body=%s", resp.StatusCode, string(body))
}
var jumioResp JumioInitResponse
err = json.Unmarshal(body, &jumioResp)
if err != nil {
return nil, err
}
return &jumioResp, nil
}