Commit Graph

3842 Commits

Author SHA1 Message Date
Sacha Al Himdani
c026f67bd9 Add vendor publish to document system
Replace the old snapshot-based system for vendors with the publish
document system, mirroring the prior processing activity / DPIA / TIA
migration. Includes the GraphQL mutation, MCP tool, CLI command, n8n
operation, frontend publish dialog, e2e tests, and a prosemirror
register template covering vendor profile fields plus per-vendor
sections for services, contacts, risk assessments, compliance reports,
BAA and DPA agreements.

The vendor register lives as a generated DocumentTypeRegister document
on the organization, reused across publishes (the major version bumps
on every republish). Approvers can be passed in to create a draft
pending approval; otherwise the version is published immediately. The
frontend Vendors page exposes a Publish button and a Document link
button when the document exists, and pre-fills the previous default
approvers.

Remove snapshot mode entirely from vendors and their sub-entities: drop
snapshotId/sourceId from GraphQL Vendor type and VendorFilter; remove
SnapshotsTypeVendors from the snapshot registry and delete
Vendors.Snapshot, VendorSnapshotter interface and all
*.InsertVendorSnapshots methods on contacts, services, risk
assessments, compliance reports, BAA and DPA. Drop the snapshot routes
and banner from the frontend. The snapshot_id columns remain in the
database but are now filtered out with snapshot_id IS NULL.

Add Get/Upsert/Clear GeneratedDocumentID methods on Vendor backed by a
new vendors_document_id column on generated_documents, matching the
ProcessingActivity/Finding/Obligation pattern.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-29 16:24:29 +02:00
Émile Ré
5629c8ccc0 Release v0.175.0 2026-04-29 18:05:54 +04:00
Bryan Frimin
79d4730806 Drop IntrospectToken doc comment
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-04-29 17:59:11 +04:00
Bryan Frimin
2418079785 Introspect OAuth2 refresh tokens
RFC 7662 lets clients introspect any OAuth2 token, but the endpoint
only resolved access tokens. Look up refresh tokens too, honor the
optional token_type_hint to drive lookup order with a fallback to the
other table, and report revoked or expired refresh tokens as inactive.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-04-29 17:59:09 +04:00
Bryan Frimin
62f05b3ff2 Invalidate sessions on password change and reset
Session validity was decoupled from credential rotation: changing
a password (logged-in flow) or completing a forgot-password reset
left every existing iam_sessions row valid until its idle TTL.
A user who saw their account compromised on another device had
no way to actually evict that device by rotating the password.

Inside the same DB transaction as the password update, expire the
identity's other active sessions:

- ChangePassword keeps the caller's current session and revokes
  every other session for the identity, so the user is not
  logged out of the browser they just used.
- ResetPassword has no caller session (the user is anonymous,
  authenticated only by a stateless token) and revokes all of
  the identity's active sessions.

The session middleware already rejects rows with expire_reason
set, so revoked sessions are kicked out on the next request
without any middleware change.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-04-29 17:57:19 +04:00
Bryan Frimin
34d8bf10a2 Use forwarded headers for SCIM event client IP
The SCIM event handler read the client address from
r.RemoteAddr only, so when probod runs behind an HTTP
load balancer every event row recorded the load
balancer's internal IP. Switch to clientip.Extract,
which honors the Forwarded / X-Forwarded-For headers
already validated by trustedproxy middleware.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-04-29 17:56:26 +04:00
Émile Ré
9920093c22 Use rightmost IP from forwarded headers
A client can prepend a spoofed entry to X-Forwarded-For before
the request reaches our load balancer. Taking the first value
would return the attacker's address. Since we sit behind a
single trusted LB that appends the real client IP as the last
entry, switch to rightmost extraction for both X-Forwarded-For
and RFC 7239 Forwarded headers.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-29 14:16:37 +04:00
Émile Ré
c0d96e662e Fix harcoded sandbox name
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-29 12:48:45 +04:00
Émile Ré
36c3d7649f Remove unused dependency
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-29 12:48:45 +04:00
Émile Ré
5e78592024 Add sandbox boot logs cmd
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-29 12:48:44 +04:00
Émile Ré
f0ebfe67fa Review fixes
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-29 12:48:44 +04:00
Émile Ré
d31bd6ec76 Use make sandbox-* targets in sandbox doc
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-29 12:48:44 +04:00
Émile Ré
072e9bc4f9 Wait for healthy stack before start probod
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-29 12:48:44 +04:00
Émile Ré
dbc5827357 Fix node_modules install + optimize go install by mounting go mod folder into VM
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-29 12:48:44 +04:00
Émile Ré
195fa74109 Unify systemctl services start and remove make build instructions
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-29 12:48:43 +04:00
Émile Ré
cd73bc1d2d Create targets for generate and embed, replace SKIP_APPS with WITH_APPS
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-29 12:48:43 +04:00
Émile Ré
ae47a960ef Fix sandbox provision script
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-29 12:48:43 +04:00
Émile Ré
6a05c22356 Use variable for target name
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-29 12:48:43 +04:00
Émile Ré
c043a7f1f5 Extract config structs into pkg/probodconfig
probod-bootstrap only needs the config struct definitions for
YAML marshaling but transitively pulled in ~40 heavy runtime
dependencies via pkg/probod. Move all config types and their
methods to a new pkg/probodconfig package and re-export them
from pkg/probod via type aliases for backward compatibility.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-29 12:48:43 +04:00
Émile Ré
983331e4dd Update avatar initials colors
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-29 11:58:49 +04:00
Sacha Al Himdani
ba8bce2ad3 Add processing activity, DPIA and TIA publish to document system
Replace the old PDF/snapshot-based exports for processing activities,
Data Protection Impact Assessments and Transfer Impact Assessments with
the publish document system. Includes GraphQL mutations, MCP tools, CLI
commands, n8n operations, frontend publish dialogs, e2e tests, and
prosemirror register templates that mirror the previous PDF layouts.

Each register lives as a generated DocumentTypeRegister document on the
organization, reused across publishes (the major version bumps on every
republish). Approvers can be passed in to create a draft pending
approval; otherwise the version is published immediately. The frontend
ProcessingActivities page exposes a Publish dropdown per register and a
Document link button per active tab, pre-fills the previous default
approvers, and navigates to the published document on success.

Remove snapshot mode entirely from these three entities: drop snapshotId
and sourceId from GraphQL schemas, types, filters, resolvers, MCP spec,
frontend routes and pages; remove SnapshotsTypeProcessingActivities from
the snapshot registry and delete the ProcessingActivities.Snapshot,
ProcessingActivitySnapshotter interface and *.InsertProcessingActivitySnapshots
methods. The snapshot_id columns remain in the database but are now
filtered out with snapshot_id IS NULL.

Add Get/Upsert/Clear GeneratedDocumentID methods on each entity type
(ProcessingActivity, DataProtectionImpactAssessment,
TransferImpactAssessment) backed by new columns in the generated_documents
table, matching the Finding/Obligation pattern.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-28 18:07:46 +02:00
Sacha Al Himdani
be294599ec Release v0.174.0
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-28 13:36:07 +02:00
Émile Ré
e850069b07 Fix consent records version coercion and cache key
Add strict numeric validation to all version filter refetch
paths and include orderBy in @connection filters to prevent
cache collisions across sort orders.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-28 15:28:18 +04:00
Émile Ré
c23f9591a3 Fix invalid input hover border
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-28 15:28:18 +04:00
Émile Ré
eebec9deb3 Fix js lint
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-28 15:28:18 +04:00
Émile Ré
b9835f0f25 Add cookie banner and category dataloaders
Batch-load CookieBanner and CookieCategory entities via
dataloadgen instead of making individual service calls in
GraphQL resolvers, matching the existing dataloader pattern
used for organizations, frameworks, etc.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-28 15:28:18 +04:00
Émile Ré
d9b0d5f44d Remove useless nil guards
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-28 15:28:18 +04:00
Émile Ré
23cf2caeba Add missing authorize calls in cookie banner resolvers
Resolvers for CookieCategory, Organization, CookieBanner,
Translations, and CookieBannerVersion.Categories were either
missing authorization checks or returning ID-only stubs
without querying the database. This fixes both issues by
adding proper authorize calls and fetching full entities.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-28 15:28:17 +04:00
Émile Ré
9b83e319a0 Add consent record detail page
Display record attributes and parsed consent data with
per-category consent state and cookies from the banner
version snapshot. The page lives outside the config layout
with its own breadcrumb navigation.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-28 15:28:17 +04:00
Émile Ré
ff2c7b9cce Fix invalid input
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-28 15:28:17 +04:00
Émile Ré
84632fe795 Filter consent records by version number
Replace the opaque cookieBannerVersionId filter with an
integer version filter. The SQL filter now resolves the
version number via a subquery against cookie_banner_versions.

Also fix the CookieBannerVersion resolver on consent records
to load the full version from the database instead of
returning a stub with only the ID set (which caused the
version to always display as 0).

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-28 15:28:17 +04:00
Émile Ré
4147239fbc Add consent records tab to cookie banner config
Exposes the cookie consent record audit trail through a new
"Consent Records" tab on the cookie banner configuration page.
The full stack includes: extended coredata filter (visitor ID,
banner version), GraphQL schema/types/resolvers, and a React
page with SortableTable (size 50) and three compliance filters
(action, visitor ID, banner version).

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-28 15:28:17 +04:00
Émile Ré
86ffb8fbd6 Reorganize tabs and add description on cookies tab
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-28 15:28:16 +04:00
Émile Ré
4b08a465d4 Reorganize cookie banner configuration pages
Move JS snippet (CodeSnippets) into Settings, move category
sorting (CategoryList) into the renamed Display page, remove
the blocking-scripts step, and rename the Snippet tab to Display.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-28 15:28:16 +04:00
Sacha Al Himdani
bdb16d4abe Add finding and obligation publish to document system
Replace the old snapshot-based approach with the new publish document
system for findings and obligations. Includes GraphQL mutations, MCP
tools, CLI commands, e2e tests, frontend publish dialogs, and
snapshot-to-document migration tools.

Remove snapshot mode entirely from findings and obligations: drop
snapshotId from GraphQL schemas, filters, resolvers, MCP spec, frontend
routes, pages, and helpers. The snapshot_id column remains in the
database but is now filtered out with snapshot_id IS NULL.

Remove auditor's ability to publish SoA.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-28 13:12:58 +02:00
Émile Ré
e473884b31 Fix copy paste in rich editor
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-28 11:17:06 +04:00
Émile Ré
9e4cf09e44 Fix turbo lint
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-27 18:39:58 +04:00
Émile Ré
535b7a6052 Relax package.json engines versions
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-27 17:15:46 +04:00
Émile Ré
c88c6ba8f6 Fix lint
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-27 16:06:45 +04:00
Émile Ré
5988070a42 Add --state and --contract-ended flags to CLI user list
Replace the --active boolean flag with two explicit filters:
--state (ACTIVE/INACTIVE) and --contract-ended (true/false).
Also add state filter support to the console GraphQL API.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-27 16:06:45 +04:00
Émile Ré
272f63828f Add state to MCP profile and refactor contract filter
Add the profile state attribute (ACTIVE/INACTIVE) to the MCP
Profile schema so listUsers and getUser tools expose it, and
add a state filter to listUsers.

Rename excludeContractEnded to contractEnded across the entire
stack (MCP, GraphQL, CLI, frontend). The new boolean is two-way:
true returns only users with ended contracts, false returns only
users with active or no contract, and null returns all.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-27 16:06:44 +04:00
Émile Ré
b7a28573f7 Send SDK version as X-SDK-Version header
Move the cookie-banner SDK version from the POST consents
request body to a custom X-SDK-Version header sent on every
API call. The server now reads it from the header and the
CORS middleware allows it through preflight.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-27 16:03:03 +04:00
Émile Ré
abafd817a8 Bump @probo/cookie-banner to 0.0.4
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-27 16:02:06 +04:00
Émile Ré
7309d7fe76 Fix cookie labels color
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-27 16:02:06 +04:00
Émile Ré
e4ae05c133 Update readme
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-27 16:02:06 +04:00
Émile Ré
79c17ad3a0 Update default exports field for main entrypoint and bump to 0.0.3
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-27 16:02:06 +04:00
Émile Ré
181a790061 Fix long cookie names display
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-27 16:02:05 +04:00
Émile Ré
9d0eff6c66 Fix long cookie names display
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-27 16:02:05 +04:00
Aurélien Sibiril
c43445d487 Add Notion workspace name resolver
Notion was the only wired access-review connector without a name
resolver, so the source kept the generic "Notion" placeholder. Fetch
the workspace name from /v1/users/me (bot.workspace_name) following
the same pattern as the other resolvers, and refresh the stale scope
comment now that Notion participates in name resolution.

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-04-27 10:49:22 +02:00
Aurélien Sibiril
7934c54f42 Request Google customer directory scope for name sync
The access-review source-name worker calls Customers.Get("my_customer")
on the Google Admin SDK to resolve the Google Workspace primary domain.
That endpoint requires admin.directory.customer.readonly; without it
the request returns 403 and the source keeps the generic placeholder
name. The scope is already requested by the SCIM bridge -- align the
access-review driver with it.

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-04-27 10:49:22 +02:00