Use electronic signature for compliage page NDA

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
Bryan Frimin
2026-02-20 09:22:37 +01:00
parent c191d25e9a
commit 16503a7df4
25 changed files with 849 additions and 1125 deletions

View File

@@ -16,7 +16,6 @@ package trust
import (
"context"
"encoding/json"
"errors"
"fmt"
"time"
@@ -155,13 +154,8 @@ func (s TrustCenterAccessService) Request(
UpdatedAt: now,
}
if err := access.Insert(ctx, tx, s.svc.scope); err != nil {
return fmt.Errorf("cannot insert trust center access: %w", err)
}
// Create PENDING electronic signature when NDA is configured.
if trustCenter.NonDisclosureAgreementFileID != nil && s.svc.esign != nil {
_, err := s.svc.esign.CreateSignature(
sig, err := s.svc.esign.CreateSignature(
ctx,
tx,
&esign.CreateSignatureRequest{
@@ -174,6 +168,11 @@ func (s TrustCenterAccessService) Request(
if err != nil {
return fmt.Errorf("cannot create pending signature: %w", err)
}
access.ElectronicSignatureID = &sig.ID
}
if err := access.Insert(ctx, tx, s.svc.scope); err != nil {
return fmt.Errorf("cannot insert trust center access: %w", err)
}
}
@@ -243,93 +242,21 @@ func (s TrustCenterAccessService) Request(
return access, nil
}
func (s TrustCenterAccessService) HasAcceptedNonDisclosureAgreement(ctx context.Context, trustCenterID gid.GID, email mail.Addr) (bool, error) {
func (s TrustCenterAccessService) GetAccess(
ctx context.Context,
trustCenterID gid.GID,
email mail.Addr,
) (coredata.TrustCenterAccess, error) {
var access coredata.TrustCenterAccess
err := s.svc.pg.WithConn(ctx, func(conn pg.Conn) error {
return access.LoadByTrustCenterIDAndEmail(ctx, conn, s.svc.scope, trustCenterID, email)
})
if err != nil {
return false, nil
}
// Legacy path: check the old boolean field.
if access.HasAcceptedNonDisclosureAgreement {
return true, nil
}
// New path: check for an electronic signature in ACCEPTED or later status.
if s.svc.esign != nil {
trustCenter := &coredata.TrustCenter{}
err := s.svc.pg.WithConn(ctx, func(conn pg.Conn) error {
return trustCenter.LoadByID(ctx, conn, s.svc.scope, trustCenterID)
})
if err != nil {
return false, nil
}
if trustCenter.NonDisclosureAgreementFileID != nil {
sig, err := s.svc.esign.LoadSignatureByOrgEmailAndDocType(
ctx,
trustCenter.OrganizationID,
email.String(),
coredata.ElectronicSignatureDocumentTypeNDA,
*trustCenter.NonDisclosureAgreementFileID,
)
if err == nil {
switch sig.Status {
case coredata.ElectronicSignatureStatusAccepted,
coredata.ElectronicSignatureStatusProcessing,
coredata.ElectronicSignatureStatusCompleted:
return true, nil
}
}
}
}
return false, nil
return access, err
}
type AcceptNDARequest struct {
TrustCenterID gid.GID
Email mail.Addr
IPAddr string
}
func (s TrustCenterAccessService) AcceptNonDisclosureAgreement(ctx context.Context, req *AcceptNDARequest) error {
return s.svc.pg.WithTx(ctx, func(tx pg.Conn) error {
access := &coredata.TrustCenterAccess{}
if err := access.LoadByTrustCenterIDAndEmail(ctx, tx, s.svc.scope, req.TrustCenterID, req.Email); err != nil {
return fmt.Errorf("cannot load trust center access: %w", err)
}
trustCenter := &coredata.TrustCenter{}
if err := trustCenter.LoadByID(ctx, tx, s.svc.scope, req.TrustCenterID); err != nil {
return fmt.Errorf("cannot load trust center: %w", err)
}
acceptationLogs, err := json.Marshal(map[string]string{
"email": req.Email.String(),
"timestamp": time.Now().Format(time.RFC3339),
"ip": req.IPAddr,
})
if err != nil {
return fmt.Errorf("cannot marshal non disclosure agreement acceptation logs: %w", err)
}
access.HasAcceptedNonDisclosureAgreement = true
access.UpdatedAt = time.Now()
access.HasAcceptedNonDisclosureAgreementMetadata = acceptationLogs
access.NDAFileID = trustCenter.NonDisclosureAgreementFileID
if err := access.Update(ctx, tx, s.svc.scope); err != nil {
return fmt.Errorf("cannot update trust center access: %w", err)
}
return nil
})
}
func (s TrustCenterAccessService) LoadDocumentAccess(
func (s TrustCenterAccessService) GetDocumentAccess(
ctx context.Context,
trustCenterID gid.GID,
email mail.Addr,
@@ -372,7 +299,7 @@ func (s TrustCenterAccessService) LoadDocumentAccess(
return documentAccess, nil
}
func (s TrustCenterAccessService) LoadReportAccess(
func (s TrustCenterAccessService) GetReportAccess(
ctx context.Context,
trustCenterID gid.GID,
email mail.Addr,
@@ -415,7 +342,7 @@ func (s TrustCenterAccessService) LoadReportAccess(
return reportAccess, nil
}
func (s TrustCenterAccessService) LoadTrustCenterFileAccess(
func (s TrustCenterAccessService) GetTrustCenterFileAccess(
ctx context.Context,
trustCenterID gid.GID,
email mail.Addr,

View File

@@ -34,9 +34,8 @@ type TrustCenterService struct {
func (s TrustCenterService) Get(
ctx context.Context,
trustCenterID gid.GID,
) (*coredata.TrustCenter, *coredata.File, error) {
) (*coredata.TrustCenter, error) {
var trustCenter *coredata.TrustCenter
var file *coredata.File
err := s.svc.pg.WithConn(
ctx,
@@ -46,22 +45,15 @@ func (s TrustCenterService) Get(
return fmt.Errorf("cannot load trust center: %w", err)
}
if trustCenter.NonDisclosureAgreementFileID != nil {
file = &coredata.File{}
if err := file.LoadByID(ctx, conn, s.svc.scope, *trustCenter.NonDisclosureAgreementFileID); err != nil {
return fmt.Errorf("cannot load file: %w", err)
}
}
return nil
},
)
if err != nil {
return nil, nil, fmt.Errorf("cannot load trust center: %w", err)
return nil, fmt.Errorf("cannot load trust center: %w", err)
}
return trustCenter, file, nil
return trustCenter, nil
}
func (s TrustCenterService) GetByOrganizationID(
@@ -89,6 +81,39 @@ func (s TrustCenterService) GetByOrganizationID(
return trustCenter, nil
}
func (s TrustCenterService) GetNDAFile(
ctx context.Context,
trustCenterID gid.GID,
) (*coredata.File, error) {
var file *coredata.File
err := s.svc.pg.WithConn(
ctx,
func(conn pg.Conn) error {
trustCenter := &coredata.TrustCenter{}
if err := trustCenter.LoadByID(ctx, conn, s.svc.scope, trustCenterID); err != nil {
return fmt.Errorf("cannot load trust center: %w", err)
}
if trustCenter.NonDisclosureAgreementFileID == nil {
return nil
}
file = &coredata.File{}
if err := file.LoadByID(ctx, conn, s.svc.scope, *trustCenter.NonDisclosureAgreementFileID); err != nil {
return fmt.Errorf("cannot load file: %w", err)
}
return nil
},
)
if err != nil {
return nil, err
}
return file, nil
}
func (s TrustCenterService) GenerateNDAFileURL(
ctx context.Context,
trustCenterID gid.GID,

View File

@@ -92,7 +92,7 @@ func (s VendorService) CountForTrustCenterId(
err := s.svc.pg.WithConn(
ctx,
func(conn pg.Conn) (err error) {
trustCenter, _, err := s.svc.TrustCenters.Get(ctx, trustCenterID)
trustCenter, err := s.svc.TrustCenters.Get(ctx, trustCenterID)
if err != nil {
return fmt.Errorf("cannot load trust center: %w", err)
}