Commit Graph

744 Commits

Author SHA1 Message Date
Émile Ré
f7e41c7f24 Update mcp types.newDocumentVersion signature - panic from body
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-06 15:22:39 +04:00
Émile Ré
6d2e9dbe19 Update MCP to handle markdown for all document content tools + fix converter edge case for code fence closing
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-06 15:13:39 +04:00
Sacha Al Himdani
ef2e99d86c Add measure-document linking
Introduce the ability to link measures to documents, following the
existing pattern used by controls and risks. This includes:

- Database migration for measures_documents join table
- Coredata MeasureDocument struct with insert/delete operations
- Document service methods for listing/counting by measure ID
- Measure service CreateDocumentMapping/DeleteDocumentMapping methods
- Cleanup of measure-document mappings on document archive
- GraphQL mutations, inputs, payloads, and Measure.documents field
- DocumentConnection.TotalCount support for measure resolver
- MCP linkMeasure/unlinkMeasure updated to support documents
- MCP listMeasureDocuments tool
- Frontend MeasureDocumentsTab with LinkedDocumentsCard integration
- Authorization actions for measure document mapping
- E2e tests for measure document mapping

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-03 17:51:31 +02:00
Sacha Al Himdani
2b377a22e7 Sort employee signatures and approvals by most recently updated
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-03 17:38:28 +02:00
Sacha Al Himdani
b610a19b84 Remove no-changes guard from document version publish
Allow publishing a document version even when the content and title
are identical to the current published version.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-03 17:27:15 +02:00
Émile Ré
11a96633ec No need for saferedirect on known connectors
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-03 18:53:02 +04:00
Sacha Al Himdani
8adf26ad20 Add in-progress state to tasks
Introduce IN_PROGRESS as a new task state between TODO and DONE across
the full stack: database enum, Go backend, GraphQL, MCP, and frontend.

The task state icon now cycles forward on click (TODO → IN_PROGRESS →
DONE → TODO), and the action dropdown provides explicit "Move to"
options for any state transition. The "All" tab supports drag-and-drop
between state sections to change a task's state.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-03 08:33:37 +02:00
Sacha Al Himdani
9a418a7711 Move document type from document to document version
Follow the same pattern used for classification: document type now lives
exclusively on DocumentVersion. A migration copies existing values from
documents to their versions. The document filter uses a subquery on the
latest version. All three API surfaces (GraphQL, MCP, CLI), resolvers,
frontend, and e2e tests are updated accordingly.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-02 16:32:38 +02:00
Aurélien Sibiril
ff20b383d9 Add access review dependencies and enum tests
Add go-vcr dependency, dev config for new providers,
connector service changes for access review, connect
schema updates, and unit tests for enum Scan/Value.

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-04-02 14:49:13 +02:00
Aurélien Sibiril
244b6390cb Wire accessreview.Service into server and probod
Add AccessReview field to server.Config and api.Config,
pass through to console and MCP NewMux. Create the
service in probod and run its background workers.

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-04-02 14:37:29 +02:00
Aurélien Sibiril
b571b074db Add access review MCP tools
Add MCP tool definitions and resolvers for access review
campaigns, sources, entries, decisions, and flags. Wire
accessreview.Service into the MCP Resolver.

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-04-02 14:37:29 +02:00
Aurélien Sibiril
ebfc0b7e31 Add access review console GraphQL API
Add queries, mutations, and types for access review
campaigns, access sources, access entries with decisions
and flags, connector provider info, and provider org
listing. Wire accessreview.Service into the Resolver.

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-04-02 14:37:29 +02:00
Sacha Al Himdani
324f4ce793 Add task priority enum and rename priority to rank
The existing integer priority field represents positional ordering
within a state, not semantic importance. Rename it to rank and
introduce a new priority field with enum values URGENT, HIGH,
MEDIUM and LOW across the entire stack.

Rank is now scoped to (state, priority) so tasks are ordered
within each priority group. A generated priority_rank column
combines both fields into a single sortable integer for cursor
pagination.

Dragging a task across priority groups updates its priority
automatically based on the drop position neighbors. The backend
first moves the task to the new group then repositions it at the
target rank.

The migration defaults existing rows to MEDIUM priority and
backfills ranks per (state, priority) group.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-02 13:35:39 +02:00
Bryan Frimin
a2f0a37b7b Add UNKNOWN and NOT_IMPLEMENTED measure states
Introduce two new measure states across the full stack: database
migration, Go coredata, GraphQL schema, MCP specification, and
frontend UI (labels, badge variants, and colors).

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-04-02 10:59:25 +02:00
Émile Ré
d069201899 MCP takes markdown input for document version content
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-01 21:33:12 +04:00
Émile Ré
f3982f23f9 Sanitize upon saving
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-01 18:03:27 +04:00
Émile Ré
4bb009f25b Handle validation errors
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-01 18:03:26 +04:00
Émile Ré
12a6c21d74 Add missing MCP tool
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-01 18:03:26 +04:00
Émile Ré
cada5e010c Fix after rebase
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-01 18:03:24 +04:00
Émile Ré
cc1a53e17c Keep allowing to pass content on document creation for use cases other than frontend app
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-01 18:03:22 +04:00
Émile Ré
3a054c70ba Implement debounced auto save
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-01 18:03:17 +04:00
Sacha Al Himdani
1b811011eb Split employee document policy from core document actions
Introduce dedicated employee-scoped IAM actions and update all
resolvers and frontend mutations accordingly.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-01 15:00:54 +02:00
Sacha Al Himdani
2d11038232 Add document classification filter
Add classification as a filter-only field on documents, resolved from
the latest document version. Expose in GraphQL, MCP, and document list
UI with a selector alongside the document type filter.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-03-31 17:36:26 +02:00
Sacha Al Himdani
6baa111fed Fix chi middleware panic in trust API mux
The session-transfer route was registered before the session and member
provisioning middlewares, causing chi to panic with "all middlewares must
be defined before routes on a mux". Scope the middlewares to the graphql
route using r.Group so session-transfer remains unauthenticated.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-03-31 16:35:47 +02:00
Bryan Frimin
b58a7e8325 Style
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-31 15:04:57 +02:00
Bryan Frimin
bb910b4314 Style
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-31 14:49:21 +02:00
Bryan Frimin
8095ac6233 Validate session transfer redirect with saferedirect
The session transfer handler was blindly redirecting to the continue URL
from the signed token. Use saferedirect with a trust center domain check
to prevent open redirects, and only trigger session transfer for known
trust center custom domains instead of any non-base-URL host.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-31 14:49:21 +02:00
Bryan Frimin
84a35c90e9 Add session transfer for SSO cookies on custom domains
After OIDC login, if the redirect targets a trust center custom
domain, the callback now redirects through a session-transfer
endpoint on that domain. The endpoint verifies an HMAC-signed,
time-limited token and sets the session cookie on the custom
domain before redirecting to the final URL.

The continue URL is bound into the signed token payload to
prevent open-redirect attacks via parameter tampering.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-31 14:49:20 +02:00
Sacha Al Himdani
5d6d0bdd7f Move document classification from document to document version
Classification now lives exclusively on DocumentVersion. The field is
removed from the Document model, all SQL queries, GraphQL Document
type, SignableDocument type, UpdateDocumentInput, and MCP Document
schema.

New documents still accept classification in CreateDocumentInput,
applied to the first version. New drafts inherit classification from
the previous version. PDF generation uses the version classification.

The drawer allows editing classification on draft versions via the
updateDocumentVersion mutation. Classification is read-only on
published versions.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-03-31 14:11:57 +02:00
Sacha Al Himdani
851e585b9b Add ISC license headers to Go, TypeScript, and SQL files
Add ISC license headers to all .go, .ts, .tsx, and .sql files
using each file's git history to determine the correct copyright
year or year range. Trademarked icons (brand logos, vendor logos,
compliance framework logos) are excluded.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-03-31 13:31:30 +02:00
Bryan Frimin
419c93fc7d Fix compliance page login redirect to custom domains
SafeRedirect previously matched against a single static host string,
so OIDC callbacks always fell back to the console instead of
redirecting back to compliance pages on custom domains. Refactor
AllowedHost into a dynamic AllowedHostFunc and wire a trust-service
lookup into the connect handler so custom domain hosts are accepted.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-31 10:51:34 +02:00
Sacha Al Himdani
68bc8cf59a Add major.minor document versioning
Introduce a two-part version scheme (major.minor) for documents.
Drafts start at 0.1 and increment minor on each new draft. Publishing
as minor keeps the current version, publishing as major bumps to the
next major.0. Both current_published_major and current_published_minor
are tracked on the document for exact version lookups.

Signatures and approval quorums aggregate across all versions sharing
the same major number using CTE joins. Approval page mutations spread
the decision fragment so Relay updates the version row state without
requiring a page refresh.

GraphQL, MCP, and service layer expose separate publishMajor and
publishMinor mutations instead of a single mutation with a type enum.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-03-30 18:54:28 +02:00
Sacha Al Himdani
0920690816 Add ability to disconnect Slack channel from compliance page
Users could connect a Slack channel to their compliance page but had no
way to remove or change the connection afterward. This adds a disconnect
button with a confirmation dialog next to connected Slack channels.

- GraphQL: deleteSlackConnection mutation with resolver
- Frontend: Disconnect button using useMutation with @deleteEdge

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-03-30 15:40:21 +02:00
Sacha Al Himdani
03d77c3bab Fix duplicate organization name returning internal error
When creating an organization with a name that produces a duplicate trust
center slug, the API now returns a Conflict response instead of a
generic Internal error.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-03-27 20:26:13 +01:00
Sacha Al Himdani
999171a626 Add document approval workflow
Introduce a complete approval system for document publishing. Document
versions can now require approval from selected reviewers before being
published, with automatic publishing once all approvers have approved.

- Add approval quorum and decision tables with backfill migration
- Implement request approval, approve, and reject flows with electronic
  signature support for approve decisions
- Add employee approvals page with dedicated tab and pending approvals view
- Add changelog field to publish and request approval flows
- Pre-select previous version's approvers in the publish dialog
- Show quorum approvers in document list with 100 approver hard limit
- Expose approval workflow through GraphQL, MCP, and CLI
- Remove legacy default approvers feature entirely
- Add comprehensive e2e test coverage for approval workflows

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-03-27 19:43:20 +01:00
Sacha Al Himdani
257cbcf826 Add task priority field
Introduce a rank-style priority on tasks, scoped by
(organization_id, state). New tasks auto-assign the next
priority. Reordering uses the same CTE-based algorithm as
trust center references and compliance external URLs.
Exposed through GraphQL, MCP, and the PRIORITY order field.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-03-27 15:47:12 +01:00
Bryan Frimin
8f59eb6b8a Distinguish expired magic links from invalid tokens
When a magic link token expires, the user now sees a specific
error message ("This magic link has expired. Please request a
new one.") instead of the generic "Failed to connect" error.

This adds ErrExpiredToken to the IAM error types, checks for
statelesstoken.ErrExpiredToken in both GetMagicLinkEmail and
OpenSessionWithMagicLink, and handles it in the trust resolver
and frontend.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-27 09:15:41 +01:00
Sacha Al Himdani
8c02c53315 Update copyright headers across all Go files
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-03-25 17:38:32 +01:00
Bryan Frimin
7625096d00 Fix copyright year to 2026 for new dataloader file
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-25 15:19:47 +01:00
Bryan Frimin
812de537f9 Style
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-25 15:19:47 +01:00
Bryan Frimin
d24712344e Add GraphQL dataloaders for batched record lookups
Introduce dataloadgen-based dataloaders to batch individual
record-by-ID fetches in GraphQL resolvers into single SQL
queries. Each entity type (organization, framework, control,
vendor, document, risk, measure, task, file, report, profile)
gets a LoadByIDs method in coredata and a GetByIDs service
method with variadic arguments and dedicated collection return
types. Resolvers now use dataloader.FromContext instead of
direct service calls for single-record lookups.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-25 15:19:46 +01:00
Bryan Frimin
359f85f5da Add SEO controls and sitemap for compliance pages
Add search engine indexing toggle, robots.txt, and sitemap.xml
generation for compliance pages. Replace checkboxes with toggle
components in the compliance page UI and add an "Open" button
in the page header to quickly access the live compliance page.
The search engine indexing toggle is disabled when the compliance
page is inactive.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-24 15:55:31 +01:00
Bryan Frimin
1d3cc1c65e Use single OIDC session auth method instead of per-provider values
The OIDC provider is already tracked in iam_oidc_states.provider, so
there is no need for provider-specific session auth methods (GOOGLE,
MICROSOFT). Replace them with a single OIDC auth method.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-23 14:17:44 +01:00
Bryan Frimin
3e4a7d3638 Add OIDC login support to compliance page
Add Google and Microsoft sign-in buttons to the trust center connect
page, matching the console sign-in experience. The backend OIDC flow
already supports flexible continue URLs, so only the GraphQL schema
and frontend needed changes.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-23 14:17:44 +01:00
Bryan Frimin
23084a72a2 Add OIDC login support for Google and Microsoft providers
Implements OpenID Connect authentication flow with PKCE, JWT verification, and enterprise-only account restrictions. Adds OIDC service with JWKS caching and state management, HTTP handlers for login/callback flows, GraphQL query for available providers, and sign-in UI integration.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-23 14:17:43 +01:00
Bryan Frimin
7b320916af Add audit log feature for recording all actions
Adds audit logging that records all authorized actions performed by
users and API keys. The audit log is automatically populated whenever
the authorizer approves an action, and is queryable via GraphQL, MCP,
and CLI interfaces. Permission checks are excluded via a dry-run flag
to avoid phantom entries on page loads.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-21 19:16:19 +01:00
Bryan Frimin
190baeebed Use actual MIME type for trust center file exports
The export endpoint was hardcoding application/pdf for all trust center
files. Now the real MIME type from the stored file metadata is threaded
through the service layer and returned as a data URI, so non-PDF files
are handled correctly on the frontend. Watermarking is only applied when
the file is actually a PDF.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-20 18:01:00 +01:00
Bryan Frimin
c2e13b7968 Add MCP audit report metadata and getAuditReportUrl tool
Adds has_report, report_filename, and report_mime_type fields to Audit type to expose report attachment status. Introduces new getAuditReportUrl tool to generate presigned download URLs for audit reports. Updates NewAudit type converter to accept optional report object for enriching metadata.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-20 15:58:27 +01:00
Bryan Frimin
f11eae6b82 Add /llms.txt endpoint to trust center compliance page
Renders compliance data (frameworks, documents, audits, subprocessors, references, and external links) as a plain-text Markdown document. The endpoint supports all required visibility filters and pagination.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-20 10:14:01 +01:00
Bryan Frimin
c5589793da Allow skipping confirmation email when adding mailing list subscribers
When creating a new subscriber, operators can now check "Skip confirmation email" if they already have the recipient's consent. This creates the subscriber in confirmed status and skips sending the notification email.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-20 09:54:25 +01:00