From 0a532f17c5835cbc0e947293fe283c4ac6d72e67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89mile=20R=C3=A9?= Date: Mon, 9 Mar 2026 16:22:45 +0400 Subject: [PATCH] Remove legacy document signing endpoints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Émile Ré --- packages/emails/emails.go | 3 +- pkg/probo/document_service.go | 103 +-------------------- pkg/probo/trust_center_service.go | 2 +- pkg/server/api/console/v1/resolver.go | 123 -------------------------- 4 files changed, 3 insertions(+), 228 deletions(-) diff --git a/packages/emails/emails.go b/packages/emails/emails.go index cc0ba3b86..5ec381d67 100644 --- a/packages/emails/emails.go +++ b/packages/emails/emails.go @@ -338,7 +338,7 @@ func (p *Presenter) RenderInvitation(ctx context.Context, invitationURLPath stri return fmt.Sprintf(subjectInvitation, organizationName), textBody, htmlBody, err } -func (p *Presenter) RenderDocumentSigning(ctx context.Context, signinURLPath string, token string, organizationName string) (subject string, textBody string, htmlBody *string, err error) { +func (p *Presenter) RenderDocumentSigning(ctx context.Context, signinURLPath string, organizationName string) (subject string, textBody string, htmlBody *string, err error) { vars, err := p.getCommonVariables(ctx) if err != nil { return "", "", nil, fmt.Errorf("cannot get common variables: %w", err) @@ -346,7 +346,6 @@ func (p *Presenter) RenderDocumentSigning(ctx context.Context, signinURLPath str signingURL := baseurl.MustParse(vars.BaseURL). AppendPath(signinURLPath). - WithQuery("token", token). MustString() data := struct { diff --git a/pkg/probo/document_service.go b/pkg/probo/document_service.go index a9a721708..722063a2f 100644 --- a/pkg/probo/document_service.go +++ b/pkg/probo/document_service.go @@ -13,7 +13,6 @@ import ( "unicode" "github.com/aws/aws-sdk-go-v2/service/s3" - "github.com/jackc/pgx/v5" "go.gearno.de/crypto/uuid" "go.gearno.de/kit/pg" "go.probo.inc/probo/packages/emails" @@ -23,7 +22,6 @@ import ( "go.probo.inc/probo/pkg/html2pdf" "go.probo.inc/probo/pkg/mail" "go.probo.inc/probo/pkg/page" - "go.probo.inc/probo/pkg/statelesstoken" "go.probo.inc/probo/pkg/validator" "go.probo.inc/probo/pkg/watermarkpdf" ) @@ -79,11 +77,6 @@ type ( SignatoryIDs []gid.GID } - SigningRequestData struct { - OrganizationID gid.GID `json:"organization_id"` - PeopleID gid.GID `json:"people_id"` - } - BulkPublishVersionsRequest struct { DocumentIDs []gid.GID PublishedBy gid.GID @@ -137,8 +130,6 @@ func (udvr *UpdateDocumentVersionRequest) Validate() error { } const ( - TokenTypeSigningRequest = "signing_request" - documentExportEmailExpiresIn = 24 * time.Hour maxFilenameLength = 200 @@ -593,59 +584,6 @@ func (s *DocumentService) Create( return document, documentVersion, nil } -func (s *DocumentService) ListSigningRequests( - ctx context.Context, - organizationID gid.GID, - profileID gid.GID, -) ([]map[string]any, error) { - q := ` -SELECT - p.title, - pv.id AS document_version_id, - o.name AS organization_name -FROM - documents p - INNER JOIN document_versions pv ON pv.document_id = p.id - INNER JOIN document_version_signatures pvs ON pvs.document_version_id = pv.id - INNER JOIN organizations o ON o.id = p.organization_id -WHERE - p.tenant_id = $1 - AND pvs.signed_by_profile_id = $2 - AND pvs.signed_at IS NULL - AND pv.status = 'PUBLISHED' - AND pv.version_number = ( - SELECT MAX(pv2.version_number) - FROM document_versions pv2 - WHERE pv2.document_id = pv.document_id - AND pv2.status = 'PUBLISHED' - ) -` - - var results []map[string]any - err := s.svc.pg.WithConn( - ctx, - func(conn pg.Conn) error { - rows, err := conn.Query(ctx, q, s.svc.scope.GetTenantID(), profileID) - if err != nil { - return fmt.Errorf("cannot query documents: %w", err) - } - - results, err = pgx.CollectRows(rows, pgx.RowToMap) - if err != nil { - return err - } - - return nil - }, - ) - - if err != nil { - return nil, err - } - - return results, nil -} - func (s *DocumentService) SendSigningNotifications( ctx context.Context, organizationID gid.GID, @@ -664,25 +602,11 @@ func (s *DocumentService) SendSigningNotifications( } for _, signatory := range signatories { - token, err := statelesstoken.NewToken( - s.svc.tokenSecret, - TokenTypeSigningRequest, - time.Hour*24*30, - SigningRequestData{ - OrganizationID: organizationID, - PeopleID: signatory.ID, - }, - ) - if err != nil { - return fmt.Errorf("cannot create signing request token: %w", err) - } - emailPresenter := emails.NewPresenter(s.svc.fileManager, s.svc.bucket, s.svc.baseURL, signatory.FullName) subject, textBody, htmlBody, err := emailPresenter.RenderDocumentSigning( ctx, - "/documents/signing-requests", - token, + "/organizations/"+organizationID.String()+"/employee", organization.Name, ) if err != nil { @@ -713,31 +637,6 @@ func (s *DocumentService) SendSigningNotifications( return nil } -func (s *DocumentService) SignDocumentVersion( - ctx context.Context, - documentVersionID gid.GID, - signatory gid.GID, -) error { - err := s.svc.pg.WithTx( - ctx, - func(conn pg.Conn) error { - var err error - _, err = s.signDocumentVersionInTx(ctx, conn, documentVersionID, signatory) - if err != nil { - return fmt.Errorf("cannot sign document version: %w", err) - } - - return nil - }, - ) - - if err != nil { - return fmt.Errorf("cannot sign document version: %w", err) - } - - return nil -} - func (s *DocumentService) SignDocumentVersionByIdentity( ctx context.Context, documentVersionID gid.GID, diff --git a/pkg/probo/trust_center_service.go b/pkg/probo/trust_center_service.go index 29deaa367..48dbff5d8 100644 --- a/pkg/probo/trust_center_service.go +++ b/pkg/probo/trust_center_service.go @@ -637,7 +637,7 @@ func (s *TrustCenterService) EmailPresenterConfig(ctx context.Context, complianc baseURL := url.URL{ Scheme: parsedBaseURL.Scheme, Host: parsedBaseURL.Host, - Path: "/trust/" + compliancePage.Slug, + Path: "/trust/" + compliancePage.ID.String(), } if customDomain != nil && customDomain.SSLStatus == coredata.CustomDomainSSLStatusActive { diff --git a/pkg/server/api/console/v1/resolver.go b/pkg/server/api/console/v1/resolver.go index 3702f358d..48acb9a55 100644 --- a/pkg/server/api/console/v1/resolver.go +++ b/pkg/server/api/console/v1/resolver.go @@ -18,14 +18,11 @@ package console_v1 import ( "context" - "encoding/json" "fmt" "net/http" "net/url" - "strings" "github.com/go-chi/chi/v5" - "go.gearno.de/crypto/uuid" "go.gearno.de/kit/httpserver" "go.gearno.de/kit/log" "go.probo.inc/probo/pkg/baseurl" @@ -40,7 +37,6 @@ import ( "go.probo.inc/probo/pkg/server/api/authn" "go.probo.inc/probo/pkg/server/api/authz" "go.probo.inc/probo/pkg/server/api/console/v1/types" - "go.probo.inc/probo/pkg/statelesstoken" ) type ( @@ -196,125 +192,6 @@ func NewMux( }) }) - r.Get( - "/documents/signing-requests", - func(w http.ResponseWriter, r *http.Request) { - token := r.Header.Get("Authorization") - if token == "" { - http.Error(w, "token is required", http.StatusUnauthorized) - return - } - - token = strings.TrimPrefix(token, "Bearer ") - data, err := statelesstoken.ValidateToken[probo.SigningRequestData](tokenSecret, probo.TokenTypeSigningRequest, token) - if err != nil { - http.Error(w, "invalid token", http.StatusUnauthorized) - return - } - - svc := proboSvc.WithTenant(data.Data.OrganizationID.TenantID()) - - requests, err := svc.Documents.ListSigningRequests(r.Context(), data.Data.OrganizationID, data.Data.PeopleID) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - w.WriteHeader(http.StatusOK) - if err := json.NewEncoder(w).Encode(requests); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - }, - ) - - r.Get( - "/documents/signing-requests/{document_version_id}/pdf", - func(w http.ResponseWriter, r *http.Request) { - token := r.URL.Query().Get("token") - if token == "" { - http.Error(w, "token is required", http.StatusUnauthorized) - return - } - - data, err := statelesstoken.ValidateToken[probo.SigningRequestData](tokenSecret, probo.TokenTypeSigningRequest, token) - if err != nil { - http.Error(w, "invalid token", http.StatusUnauthorized) - return - } - - documentVersionID, err := gid.ParseGID(chi.URLParam(r, "document_version_id")) - if err != nil { - http.Error(w, "invalid document version id", http.StatusBadRequest) - return - } - - svc := proboSvc.WithTenant(data.Data.OrganizationID.TenantID()) - - // Get the people to get their email for watermark - profile, err := iamSvc.OrganizationService.GetProfile(r.Context(), data.Data.PeopleID) - if err != nil { - http.Error(w, "cannot get user", http.StatusInternalServerError) - return - } - - // Generate PDF with watermark - pdfData, err := svc.Documents.ExportPDF(r.Context(), documentVersionID, probo.ExportPDFOptions{ - WithWatermark: true, - WatermarkEmail: &profile.EmailAddress, - WithSignatures: false, - }) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - uuid, err := uuid.NewV7() - if err != nil { - http.Error(w, "cannot generate uuid", http.StatusInternalServerError) - return - } - - w.Header().Set("Content-Type", "application/pdf") - w.Header().Set("Content-Disposition", fmt.Sprintf("inline; filename=\"%s.pdf\"", uuid.String())) - w.WriteHeader(http.StatusOK) - _, _ = w.Write(pdfData) - }, - ) - - r.Post( - "/documents/signing-requests/{document_version_id}/sign", - func(w http.ResponseWriter, r *http.Request) { - token := r.Header.Get("Authorization") - if token == "" { - http.Error(w, "token is required", http.StatusUnauthorized) - return - } - - token = strings.TrimPrefix(token, "Bearer ") - data, err := statelesstoken.ValidateToken[probo.SigningRequestData](tokenSecret, probo.TokenTypeSigningRequest, token) - if err != nil { - http.Error(w, "invalid token", http.StatusUnauthorized) - return - } - - documentVersionID, err := gid.ParseGID(chi.URLParam(r, "document_version_id")) - if err != nil { - http.Error(w, "invalid document version id", http.StatusBadRequest) - return - } - - svc := proboSvc.WithTenant(data.Data.OrganizationID.TenantID()) - - if err := svc.Documents.SignDocumentVersion(r.Context(), documentVersionID, data.Data.PeopleID); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - w.WriteHeader(http.StatusOK) - }, - ) - return r }