Filter inactive people from signature request recipients
The signature request recipient lists (both the multi-select dialog and the document signatures page) included people who were inactive via SCIM deactivation. The existing filter only excluded people with ended contracts but not those with an INACTIVE state. This adds state: ACTIVE to the ProfileFilter in both frontend queries and introduces a server-side ErrProfileInactive validation in the RequestSignature and BulkRequestSignatures service methods to reject inactive profiles even if called directly via API. Co-authored-by: Émile Ré <nemile.re@gmail.com> Signed-off-by: Émile Ré <emile@getprobo.com> Signed-off-by: Émile Ré <emile@probo.com>
This commit is contained in:
@@ -196,7 +196,7 @@ function PeopleList({
|
||||
signatureDocumentsDialogPeopleQuery,
|
||||
{
|
||||
organizationId,
|
||||
filter: { contractEnded: false },
|
||||
filter: { contractEnded: false, state: "ACTIVE" },
|
||||
},
|
||||
);
|
||||
const {
|
||||
|
||||
@@ -27,7 +27,7 @@ export const documentSignaturesPageQuery = graphql`
|
||||
query DocumentSignaturesPageQuery($documentId: ID! $organizationId: ID! $versionId: ID! $versionSpecified: Boolean!) {
|
||||
organization: node(id: $organizationId) {
|
||||
__typename
|
||||
...DocumentSignatureList_peopleFragment @arguments(filter: { contractEnded: false })
|
||||
...DocumentSignatureList_peopleFragment @arguments(filter: { contractEnded: false, state: ACTIVE })
|
||||
}
|
||||
# We use this on /documents/:documentId
|
||||
document: node(id: $documentId) @skip(if: $versionSpecified) {
|
||||
|
||||
@@ -97,6 +97,10 @@ type (
|
||||
ProfileID gid.GID
|
||||
}
|
||||
|
||||
ErrProfileInactive struct {
|
||||
ProfileID gid.GID
|
||||
}
|
||||
|
||||
CreateDocumentRequest struct {
|
||||
OrganizationID gid.GID
|
||||
Title string
|
||||
@@ -278,6 +282,10 @@ func (e ErrProfileContractEnded) Error() string {
|
||||
return fmt.Sprintf("cannot use profile %q: contract has ended", e.ProfileID)
|
||||
}
|
||||
|
||||
func (e ErrProfileInactive) Error() string {
|
||||
return fmt.Sprintf("cannot use profile %q: profile is inactive", e.ProfileID)
|
||||
}
|
||||
|
||||
func (s *DocumentService) Get(
|
||||
ctx context.Context,
|
||||
documentID gid.GID,
|
||||
@@ -971,6 +979,9 @@ func (s *DocumentService) BulkRequestSignatures(
|
||||
|
||||
now := time.Now()
|
||||
for _, p := range *profiles {
|
||||
if p.State == coredata.ProfileStateInactive {
|
||||
return &ErrProfileInactive{ProfileID: p.ID}
|
||||
}
|
||||
if p.ContractEndDate != nil && p.ContractEndDate.Before(now) {
|
||||
return &ErrProfileContractEnded{ProfileID: p.ID}
|
||||
}
|
||||
@@ -1082,6 +1093,10 @@ func (s *DocumentService) RequestSignature(
|
||||
return fmt.Errorf("cannot load signatory profile: %w", err)
|
||||
}
|
||||
|
||||
if profile.State == coredata.ProfileStateInactive {
|
||||
return &ErrProfileInactive{ProfileID: profile.ID}
|
||||
}
|
||||
|
||||
if profile.ContractEndDate != nil && profile.ContractEndDate.Before(time.Now()) {
|
||||
return &ErrProfileContractEnded{ProfileID: profile.ID}
|
||||
}
|
||||
|
||||
@@ -1296,6 +1296,10 @@ func (r *mutationResolver) RequestSignature(ctx context.Context, input types.Req
|
||||
return nil, gqlutils.Conflict(ctx, errContractEnded)
|
||||
}
|
||||
|
||||
if errInactive, ok := errors.AsType[*probo.ErrProfileInactive](err); ok {
|
||||
return nil, gqlutils.Conflict(ctx, errInactive)
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot request signature", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
@@ -1341,6 +1345,10 @@ func (r *mutationResolver) BulkRequestSignatures(ctx context.Context, input type
|
||||
return nil, gqlutils.Conflict(ctx, errContractEnded)
|
||||
}
|
||||
|
||||
if errInactive, ok := errors.AsType[*probo.ErrProfileInactive](err); ok {
|
||||
return nil, gqlutils.Conflict(ctx, errInactive)
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot bulk request signatures", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user