Handle missing NDA

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2025-10-03 16:52:32 +02:00
parent dc74feeefb
commit 4adefef448
5 changed files with 64 additions and 29 deletions

View File

@@ -27,7 +27,8 @@ export function MainLayout(props: Props) {
const baseTabUrl = `/trust/${trustCenter.slug}`;
const showNDADialog =
trustCenter.isUserAuthenticated &&
!trustCenter.hasAcceptedNonDisclosureAgreement;
!trustCenter.hasAcceptedNonDisclosureAgreement &&
trustCenter.ndaFileUrl;
return (
<AuthProvider isAuthenticated={trustCenter.isUserAuthenticated}>
<TrustCenterProvider trustCenter={trustCenter}>

View File

@@ -0,0 +1,7 @@
ALTER TABLE trust_center_accesses ADD COLUMN nda_file_id TEXT;
ALTER TABLE trust_center_accesses ADD CONSTRAINT trust_center_accesses_nda_file_id_fkey
FOREIGN KEY (nda_file_id)
REFERENCES files(id)
ON UPDATE CASCADE
ON DELETE RESTRICT;

View File

@@ -38,6 +38,7 @@ type (
Active bool `db:"active"`
HasAcceptedNonDisclosureAgreement bool `db:"has_accepted_non_disclosure_agreement"`
HasAcceptedNonDisclosureAgreementMetadata json.RawMessage `db:"has_accepted_non_disclosure_agreement_metadata"`
NDAFileID *gid.GID `db:"nda_file_id"`
CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"`
}
@@ -78,6 +79,7 @@ SELECT
active,
has_accepted_non_disclosure_agreement,
has_accepted_non_disclosure_agreement_metadata,
nda_file_id,
created_at,
updated_at
FROM
@@ -129,6 +131,7 @@ SELECT
active,
has_accepted_non_disclosure_agreement,
has_accepted_non_disclosure_agreement_metadata,
nda_file_id,
created_at,
updated_at
FROM
@@ -227,7 +230,8 @@ UPDATE trust_center_accesses SET
active = @active,
updated_at = @updated_at,
has_accepted_non_disclosure_agreement = @has_accepted_non_disclosure_agreement,
has_accepted_non_disclosure_agreement_metadata = @has_accepted_non_disclosure_agreement_metadata
has_accepted_non_disclosure_agreement_metadata = @has_accepted_non_disclosure_agreement_metadata,
nda_file_id = @nda_file_id
WHERE
%s
AND id = @id
@@ -242,6 +246,7 @@ WHERE
"updated_at": tca.UpdatedAt,
"has_accepted_non_disclosure_agreement": tca.HasAcceptedNonDisclosureAgreement,
"has_accepted_non_disclosure_agreement_metadata": tca.HasAcceptedNonDisclosureAgreementMetadata,
"nda_file_id": tca.NDAFileID,
}
maps.Copy(args, scope.SQLArguments())
@@ -297,6 +302,7 @@ SELECT
active,
has_accepted_non_disclosure_agreement,
has_accepted_non_disclosure_agreement_metadata,
nda_file_id,
created_at,
updated_at
FROM

View File

@@ -158,18 +158,25 @@ func (r *mutationResolver) ExportDocumentPDF(ctx context.Context, input types.Ex
return nil, fmt.Errorf("cannot export document PDF: %w", err)
}
hasAcceptedNDA := false
userData := UserFromContext(ctx)
if userData != nil {
hasAcceptedNDA = true
}
tokenData := TokenAccessFromContext(ctx)
if tokenData != nil {
tokenData := TokenAccessFromContext(ctx)
hasAcceptedNDA, err = privateTrustService.TrustCenterAccesses.HasAcceptedNonDisclosureAgreement(ctx, tokenData.TrustCenterID, tokenData.GetEmail())
ndaExists := true
hasAcceptedNDA := false
trustCenter, _, err := privateTrustService.TrustCenters.Get(ctx, tokenData.TrustCenterID)
if err != nil {
panic(fmt.Errorf("cannot check if user has accepted NDA: %w", err))
panic(fmt.Errorf("cannot get trust center: %w", err))
}
if trustCenter.NonDisclosureAgreementFileID == nil {
ndaExists = false
}
if ndaExists {
tokenData := TokenAccessFromContext(ctx)
hasAcceptedNDA, err = privateTrustService.TrustCenterAccesses.HasAcceptedNonDisclosureAgreement(ctx, tokenData.TrustCenterID, tokenData.GetEmail())
if err != nil {
panic(fmt.Errorf("cannot check if user has accepted NDA: %w", err))
}
}
documentAccess, err := privateTrustService.TrustCenterAccesses.LoadDocumentAccess(ctx, tokenData.TrustCenterID, tokenData.GetEmail(), input.DocumentID)
@@ -180,12 +187,13 @@ func (r *mutationResolver) ExportDocumentPDF(ctx context.Context, input types.Ex
if !documentAccess.Active {
return nil, fmt.Errorf("access denied: no permission to access this document")
}
if ndaExists && !hasAcceptedNDA {
return nil, fmt.Errorf("user has not accepted NDA")
}
}
if !hasAcceptedNDA {
return nil, fmt.Errorf("user has not accepted NDA")
}
userData := UserFromContext(ctx)
userEmail := ""
if userData != nil {
userEmail = userData.EmailAddress
@@ -211,17 +219,24 @@ func (r *mutationResolver) ExportReportPDF(ctx context.Context, input types.Expo
return nil, fmt.Errorf("cannot export report PDF: %w", err)
}
hasAcceptedNDA := false
userData := r.UserFromContext(ctx)
if userData != nil {
hasAcceptedNDA = true
}
tokenData := TokenAccessFromContext(ctx)
if tokenData != nil {
hasAcceptedNDA, err = privateTrustService.TrustCenterAccesses.HasAcceptedNonDisclosureAgreement(ctx, tokenData.TrustCenterID, tokenData.GetEmail())
ndaExists := true
hasAcceptedNDA := false
trustCenter, _, err := privateTrustService.TrustCenters.Get(ctx, tokenData.TrustCenterID)
if err != nil {
panic(fmt.Errorf("cannot check if user has accepted NDA: %w", err))
panic(fmt.Errorf("cannot get trust center: %w", err))
}
if trustCenter.NonDisclosureAgreementFileID == nil {
ndaExists = false
}
if ndaExists {
hasAcceptedNDA, err = privateTrustService.TrustCenterAccesses.HasAcceptedNonDisclosureAgreement(ctx, tokenData.TrustCenterID, tokenData.GetEmail())
if err != nil {
panic(fmt.Errorf("cannot check if user has accepted NDA: %w", err))
}
}
reportAccess, err := privateTrustService.TrustCenterAccesses.LoadReportAccess(ctx, tokenData.TrustCenterID, tokenData.GetEmail(), input.ReportID)
@@ -232,12 +247,13 @@ func (r *mutationResolver) ExportReportPDF(ctx context.Context, input types.Expo
if !reportAccess.Active {
return nil, fmt.Errorf("access denied: no permission to access this report")
}
if ndaExists && !hasAcceptedNDA {
return nil, fmt.Errorf("user has not accepted NDA")
}
}
if !hasAcceptedNDA {
return nil, fmt.Errorf("user has not accepted NDA")
}
userData := UserFromContext(ctx)
userEmail := ""
if userData != nil {
userEmail = userData.EmailAddress
@@ -519,13 +535,12 @@ func (r *reportResolver) HasUserRequestedAccess(ctx context.Context, obj *types.
func (r *trustCenterResolver) NdaFileURL(ctx context.Context, obj *types.TrustCenter) (*string, error) {
privateTrustService, err := r.PrivateTrustService(ctx, obj.ID.TenantID())
if err != nil {
// Return nil but no error if the user is not authenticated
return nil, nil
}
fileURL, err := privateTrustService.TrustCenters.GenerateNDAFileURL(ctx, obj.ID, 15*time.Minute)
if err != nil {
return nil, fmt.Errorf("failed to generate NDA file URL: %w", err)
return nil, nil
}
return &fileURL, nil

View File

@@ -203,6 +203,11 @@ func (s TrustCenterAccessService) AcceptNonDisclosureAgreement(ctx context.Conte
return fmt.Errorf("cannot load trust center access: %w", err)
}
trustCenter := &coredata.TrustCenter{}
if err := trustCenter.LoadByID(ctx, tx, s.svc.scope, trustCenterID); err != nil {
return fmt.Errorf("cannot load trust center: %w", err)
}
acceptationLogs, err := json.Marshal(map[string]string{
"email": email,
"timestamp": time.Now().Format(time.RFC3339),
@@ -215,6 +220,7 @@ func (s TrustCenterAccessService) AcceptNonDisclosureAgreement(ctx context.Conte
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)
}