Commit Graph

527 Commits

Author SHA1 Message Date
Émile Ré
ad90fab080 Release @probo/cookie-banner/v0.3.0
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-05-07 16:24:32 +04:00
Émile Ré
1b2b72f29e Release @probo/n8n-nodes-probo/v0.183.0
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-05-07 16:24:17 +04:00
Émile Ré
806bd672ed Surface regulation and country code enums across API layers
Add proper enum types for Regulation and CountryCode in GraphQL
(with @goModel/@goEnum directives) and MCP (as standalone reusable
schemas with $ref). Update CLI, console UI, and n8n to include
the new fields.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-05-07 15:13:48 +04:00
Émile Ré
72fa79629f Review fixes
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-05-07 15:13:43 +04:00
Émile Ré
ca15a355e8 Defer banner button validation until config is loaded
The validation now runs on probo-ready instead of connectedCallback
so it can check config.texts to decide which buttons are required
for the active consent mode.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-05-07 15:13:42 +04:00
Émile Ré
b4bb8715ee Adapt cookie banner UI and texts per regulation
The server now resolves regulation-specific translations
(opt-out notice for CCPA, simple notice when no regulation
applies) and remaps text keys before returning the config.
The client hides buttons whose text is empty, so the banner
layout adapts without client-side consent-mode logic.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-05-07 15:13:42 +04:00
Émile Ré
4598506076 Extract shared types and add Regulation type with parsing methods
Move cookie banner types (CookieItem, Category, Regulation, BannerConfig,
etc.) into a dedicated types.ts file. Add a coredata.Regulation type with
parsing, JSON marshaling, and database scanning methods. Hardcode the
geoloc-import data directory since the submodule path is fixed.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-05-07 15:13:42 +04:00
Émile Ré
f695b90b19 Store detected regulation in consent records and expose it in SDK
Add a regulation column to cookie_consent_records so each consent
captures which privacy law was in effect. Thread the value from the
handler's geoloc resolution through the service into the DB insert.

On the SDK side, add a Regulation union type to BannerConfig and expose
it via a getter on CookieBannerClient and in the probo-ready event
detail so themed-banner consumers can adapt their UI per regulation.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-05-07 15:13:42 +04:00
Bryan Frimin
5274937e61 Release @probo/n8n-nodes-probo/v0.182.0
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-05-06 16:54:36 +02:00
Bryan Frimin
ac526fb54d Split release into per-track packages
Each shippable artifact (prb, probod server group, probod-bootstrap,
@probo/n8n-nodes-probo, @probo/cookie-banner) now has its own version
file, its own CHANGELOG.md, its own annotated-tag scheme of the form
<track>/v<version>, and its own GitHub Actions release workflow. The
unified release.yaml is removed; the unified CHANGELOG.md becomes a
short index pointing at each per-track file, with the prior history
preserved in CHANGELOG.archive.md.

Probod's CHANGELOG carries the post-split monorepo releases (0.174.0
through 0.181.0) so the server-group history stays continuous and the
probod docker image keeps its existing version line.

contrib/claude/release.md is split into contrib/claude/release/ with
one entrypoint per track plus a README that drives the agent: detect
which tracks have user-facing commits since their last tag and skip
tracks with no relevant changes, so a release request never tags an
unchanged track. The cookie-banner and n8n-node entrypoints add an
explicit npm run build step after the version bump (build.mjs bakes
package.json's version into __SDK_VERSION__) so compile errors and
package-lock.json updates are caught before tagging.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-05-06 16:04:36 +02:00
Bryan Frimin
5e55c888c4 Add Microsoft 365 SCIM bridge and access review driver
Microsoft 365's native SCIM endpoint is unreliable, so mirror the
Google Workspace bridge over Microsoft Graph: a new MICROSOFT_365
OAuth2 connector, a SCIM bridge provider listing /v1.0/users with
$select pagination, and an access review driver that derives admin
status from /directoryRoles members. Refactor the bridge runner to
share OAuth2 plumbing across providers and surface the new bridge
type, scopes, UI card, and bootstrap env wiring.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-05-06 15:41:30 +02:00
Sacha Al Himdani
1434d8336c Allow publishing generated documents as minor versions
Generated documents (asset list, risk register, SoA, ...) previously
only ever produced a new major version. Every regeneration of an
auto-built register consumed a major number, even when the change was
trivial. They now accept a minor flag and publish as
currentMajor.currentMinor+1 when set, bypassing the approval flow.

To carry the flag through cleanly, the document publish API was
refactored. The three split mutations (publishMajor, publishMinor,
requestDocumentVersionApproval) and the two bulk variants collapse
into a single publishDocument / bulkPublishDocuments, both taking the
new minor: Boolean! and a now-required changelog: String!. The same
shape flows through the CLI ("prb document publish --minor"), the MCP
tool, the n8n operations, and the Relay dialogs, where each
generated-doc dialog gains a "Publish as minor" button. Publishing
minor without an existing major is rejected with
ErrCannotPublishMinorWithoutMajor.

This is a deliberate breaking change for callers of the prior
mutations.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-05-06 14:02:59 +02:00
Émile Ré
af6e420f54 Remove cookie_patterns legacy, migrate to tracker_patterns
Delete coredata.CookiePattern and all associated CRUD methods,
rename shared types (CookiePatternOrderField, CookiePatternFilter,
CookiePatternMatchType) to TrackerPattern equivalents, and migrate
all API surfaces (GraphQL, MCP, CLI, n8n) to tracker_pattern naming.

The worker was already migrated in the base branch; this commit
completes the removal by dropping the old GraphQL schema/resolvers,
service methods, CLI commands, and n8n operations that operated on
the legacy cookie_patterns table.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-05-06 12:26:12 +04:00
Émile Ré
54655c218b Surface last_matched_at on all API surfaces
Add lastMatchedAt to the CookiePattern GraphQL type, MCP schema,
CLI view/list commands, and n8n get/getAll operations. Run
codegen to regenerate gqlgen models and MCP types.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-05-05 11:06:53 +04:00
Sacha Al Himdani
553901e4ad Add risk publish to document system
Replace the old snapshot-based system for risks with the publish
document system, mirroring the prior vendor / 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 name, description, category, treatment,
owner, inherent and residual scoring, and notes.

The risk 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
Risks page exposes a Publish button and a Document link button when the
document exists, and pre-fills the previous default approvers.

Risks was the last remaining snapshot type, so this commit also removes
the entire snapshot system: drop snapshotId from the Risk GraphQL type
and RiskFilter; remove RiskSnapshotter, Risks.Snapshot,
InsertRiskSnapshots, and the SnapshotID/SourceID fields on Risk; delete
Snapshot, ControlSnapshot, SnapshotsType, SnapshotOrderField,
Snapshottable, the SnapshotService, the Snapshot console resolvers and
GraphQL schema, the Snapshot MCP types and operations
(list/get/take/listControlSnapshots), the snapshot CLI (prb snapshot),
the snapshot frontend pages, routes, banner, LinkedSnapshotsCard,
SnapshotGraph, snapshot helpers, and the snapshot n8n resource and
control link/unlink snapshot operations. 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 Risk backed by a new
risks_document_id column on generated_documents, matching the
ProcessingActivity/Finding/Vendor pattern. The migration command
migrate-risk-snapshots-to-documents uses raw SQL queries instead of the
Go snapshot types, since those are gone.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-05-04 14:13:42 +02:00
Émile Ré
2ceb8f4126 Fix n8n cookieConsentRecord getAll operation
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-05-02 22:13:32 +04:00
Émile Ré
3e8cd8444a Bump @probo/cookie-banner to 0.2.0
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-05-02 21:24:39 +04:00
Émile Ré
a83d313dfa Clear pending queue before stopping on 404
When flush receives a 404, stop() would re-flush remaining
pending cookies to a dead endpoint. Clear the queue first to
avoid the wasted request.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-05-02 19:42:29 +04:00
Émile Ré
33940d63ca Run cookie detection regardless of banner state
Decouple detection from the banner's active state so admins
can discover cookies before making the banner visible. The
client now starts the detector even when the config endpoint
returns 404, and the detector stops itself if the report
endpoint returns 404 (wrong or deleted banner ID).

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-05-02 19:01:13 +04:00
Émile Ré
71cad5f15e Allow clearing optional fields in n8n cookie updates
The previous fix prevented unintentional clearing of
`privacyPolicyUrl` and `maxAgeSeconds` by skipping the field
when its value was falsy, but this also removed the user's
ability to explicitly clear an existing value.

Move both fields into an `Additional Fields` collection so we
can distinguish between "not provided" (skip) and "provided
empty" (clear), matching the existing pattern in
`vendor/update.operation.ts`.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-05-02 15:35:20 +04:00
Émile Ré
1650b26fa9 Fix destructive update behavior in n8n cookie operations
Avoid clearing existing values when optional fields are left at their
defaults: only send privacyPolicyUrl/maxAgeSeconds when truthy, filter
empty entries from gcmConsentTypes, and constrain consentExpiryDays to
positive integers on create.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-05-01 20:11:37 +04:00
Émile Ré
1996545125 Add excluded field to cookie pattern operations
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-05-01 17:59:11 +04:00
Émile Ré
6f849b36a1 Add cookie banner operations to n8n node
Adds four new resources (cookieBanner, cookieCategory,
cookiePattern, cookieConsentRecord) covering all mutations
and queries from the cookie banner GraphQL resolvers.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-05-01 17:56:23 +04:00
Émile Ré
1d08760d3b Display cookie pattern source badge in category table
Show the origin of each cookie pattern (Script vs Pre-existing)
as a badge with a tooltip in the cookies configuration table.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-05-01 17:41:50 +04:00
Émile Ré
54494fc9b1 Bump version to 0.1.1
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-30 17:11:39 +04:00
Émile Ré
42a6a2f8bd Show placeholders when no prior consent exists
The activate() method was only called when consent existed (from
cookie or API). When there was no prior consent, observeAndActivate()
never ran, so visual elements with data-cookie-consent were left
without placeholders. Build default consent data from the config's
consent_mode and always call activate() at the end of load().

Also consolidate activateElements/addPlaceholders into
observeAndActivate to avoid duplicate DOM traversals.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-30 17:10:35 +04:00
Émile Ré
15ff6131e1 Fix placeholder sizing for cookie-consent elements
Expand the dimensional property allowlist with padding, box-sizing,
and positioning properties (position, top, right, bottom, left,
inset) so placeholders match the size of absolutely or sticky
positioned elements. Fall back to getComputedStyle for height when
no explicit value is found from inline styles or HTML attributes.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-30 16:59:13 +04:00
Émile Ré
bd6abccb2d Upgrade esbuild to remove vulnerability
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-30 15:52:43 +04:00
Émile Ré
336ec986d5 Update @probo/cookie-banner public exports and bump to 0.1.0
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-30 15:14:19 +04:00
Émile Ré
0d257977a1 Refactor cookie banner forms to react-hook-form
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-30 14:05:45 +04:00
Émile Ré
33abbfbb8f Link detected cookies to existing patterns on conflict
When a cookie pattern already exists for a banner, the insert
conflict caused a continue that silently dropped the detected
cookie instead of linking it to the existing pattern. Load the
existing pattern to obtain its ID and proceed with cookie
insertion.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-30 11:46:13 +04:00
Émile Ré
427bbbaf5c Move DurationInput to @probo/ui and scope pattern merge by category
Move the DurationInput component from the console app into @probo/ui
for reuse, add duration formatting helpers to @probo/helpers, and
update pattern merge to group by both category ID and prefix.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-30 11:46:12 +04:00
Émile Ré
2fe77d9ddc Fix review issues in cookie pattern handling
- Fix DurationInput fallback unit from "minutes" to "seconds" and add
  seconds as a selectable unit to prevent silent duration inflation
- Use parseFloat instead of parseInt for duration input to preserve
  fractional values
- Scope prefix merge groups by category ID to prevent cross-category
  merging
- Relink cookies and delete exact patterns even when prefix pattern
  already exists
- Prefer exact matches and longest prefix in pattern selection query
- Fix wrong error type in GetCookiePattern (ErrCookiePatternNotFound)
- Handle singular/plural in humanizeSeconds fallback branch

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-30 11:46:11 +04:00
Émile Ré
5cdaddf8b1 Store cookie durations as max_age_seconds
Replace the free-form duration TEXT column with a nullable
max_age_seconds INTEGER on both cookies and cookie_patterns
tables. The SDK detector now sends raw seconds instead of
humanized strings, eliminating locale-dependent comparisons
in the pattern merge worker. Humanization happens at display
time in the widget and console UI.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-30 11:46:11 +04:00
Émile Ré
48606f34c1 Filter browser-extension cookies from detection
Cookies set by browser extensions are not the website operator's
compliance responsibility. This adds stack-trace inspection to
filter out extension-originated document.cookie writes, and
annotates pre-existing cookies with a source field so operators
can triage them separately.

Introduces a CookieSource enum (SCRIPT / PRE_EXISTING) across
the full stack: PostgreSQL, coredata, service, HTTP handler, and
GraphQL schema. On conflict, source is upgraded from PRE_EXISTING
to SCRIPT when a page script is later observed setting the cookie.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-30 11:46:10 +04:00
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é
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
É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é
ff2c7b9cce Fix invalid input
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-28 15:28:17 +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é
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
Émile Ré
d955489d11 Bump @probo/cookie-banner version
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-24 19:28:48 +04:00