Pick up mcpgen main so go generate emits tool titles and refined
readOnlyHint/destructiveHint annotations from the schema.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
Omiting destructiveHint defaults to true in the MCP spec, so reads
must set it explicitly even though the field is only meaningful when
not read-only.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
Fill in readonly, destructive, idempotent, and openWorld on every
tool so clients can rely on explicit values instead of MCP defaults
(destructive and openWorld both default to true when omitted).
Drop the temporary mcpgen vendor from this change; that lands in a
separate pull request.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
Claude and other MCP clients use title, readOnlyHint, and
destructiveHint to present reads, writes, and deletes accurately.
Add a title to every tool, mark missing delete/unlink/cancel/void
tools as destructive, and teach mcpgen to emit those annotations
(including destructiveHint: false for non-destructive writes).
Temporary third_party/mcpgen fork until title support lands
upstream.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Only the checkbox glyph was dimmed, so disabled options still
looked clickable. Apply data-disabled styles to the whole item
for opacity, cursor, and hover.
Signed-off-by: Émile Ré <emile@probo.com>
Replace the cramped status checkboxes with a multi-select
dropdown (new DropdownCheckboxItem), and update the Relay
store to PENDING when an activation email is sent so the
row reflects the server-side state change immediately.
Signed-off-by: Émile Ré <emile@probo.com>
A debounced search could fire after status, role, kind, or sort
changed and refetch with the previous filter values, briefly
reverting the list. Cancel the pending callback before those
immediate refetches so the latest filters stick.
Signed-off-by: Émile Ré <emile@probo.com>
Address PR review feedback on the profile-state split: SAML sign-in now
activates a pending profile, deactivation counts owners against the
profile's own organization to close a last-owner bypass, the migration
leaves historical activated_at/deactivated_at NULL rather than
fabricating timestamps, and pending members are no longer rendered with
the deactivated (faded) styling.
Drop the single-value state filter in favor of the multi-value states
across the profile and signatory surfaces. Remove ProfileFilter.state
(only states[] remains) and convert the signatures profileState filter
to profileStates. Turn the console people filter, the CLI
"user list --state" flag, and the n8n listUsers and getAllSignatures
state inputs into multi-select controls, where an empty selection means
all states.
Signed-off-by: Émile Ré <emile@probo.com>
"Archive" was misleading for users: the action sets a profile to
DEACTIVATED while keeping the person in the organization. Rename it to
"deactivate" across the API, CLI, MCP, n8n, and console UI.
Consolidate the two overlapping operations into a single deactivateUser
backed by the fuller, guarded logic (SCIM guard, last-active-owner
guard, invitation expiry, signature cancellation, membership update,
webhook) and authorized via iam:membership-profile:deactivate. Remove
the archiveUser surface and the thin state-only deactivate path.
Signed-off-by: Émile Ré <emile@probo.com>
The inline owner picker on the assets table queried people without a
state filter, so deactivated profiles remained selectable as owners.
Restrict it to ACTIVE and PENDING to match the other owner pickers,
keeping pending members assignable while dropping deactivated ones.
Signed-off-by: Émile Ré <emile@probo.com>
Replace the binary profile ACTIVE/INACTIVE model with PENDING, ACTIVE,
and DEACTIVATED so invited-but-not-yet-activated members remain
assignable to assets, data, and risks instead of being treated like
deactivated users.
Add activated_at/deactivated_at timestamps and Mark* lifecycle helpers,
and update every transition (create, invite/re-invite, activation,
archive, SCIM, SAML, sessions, compliance-portal grant) to the new
states. Expose a multi-state states[] filter across coredata, GraphQL,
MCP, and the console owner pickers, which now request ACTIVE and
PENDING members.
A migration renames the membership_state enum, classifies existing
inactive profiles as PENDING from recent invitation activity, and
backfills the new timestamp columns.
Signed-off-by: Émile Ré <emile@probo.com>
Add a blank line before authSecureCookieConfig so
golangci wsl_v5 passes in lint-go.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
Add same-site to auth cookie config with lax as the default,
PROBOD_AUTH_COOKIE_SAMESITE bootstrap mapping, and validation
that rejects none unless Secure is enabled.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
Route audit-log and SCIM-event exports through export_jobs with typed
arguments, an iam BuildAndUploadExport/SendExportEmail implementation,
and a concurrent export-job worker with stale recovery. Stream JSONL via
page.WalkAll into S3, and expose the request flow on console, connect,
MCP, and CLI.
Co-authored-by: Bryan Frimin <bryan@getprobo.com>
Signed-off-by: Sacha Al Himdani <sacha@probo.com>
List rows and the viewer toolbar used the same clipboard
toast path; Ukrainian moreRegions needs one/few/many forms.
Signed-off-by: Émile Ré <emile@probo.com>
The swipe Popup keeps a CSS transform that re-roots
position:fixed, so Base UI's modal inert cutout missed
the locale trigger and blocked hover and clicks.
Signed-off-by: Émile Ré <emile@probo.com>
Keeps DocumentViewer focused on layout and preview state, and
gives the page/zoom/copy/download chrome its own home.
Signed-off-by: Émile Ré <emile@probo.com>
Unauthorized visitors still need the document identity and a
way back to the list; only the preview toolbar is withheld,
with the access CTA replacing the file body.
Signed-off-by: Émile Ré <emile@probo.com>
Sharing only copies the viewer URL, so rename the action and
expose the same control on each documents list row.
Signed-off-by: Émile Ré <emile@probo.com>
AWS-scale region lists blew out subprocessor cards. Cap the
visible labels and open the rest from a +N trigger using a
new Base UI Popover in the v2 kit.
Signed-off-by: Émile Ré <emile@probo.com>
Local Vite continue URLs use absolute localhost origins that never
pass verified custom-domain checks. Reuse AllowedOrigins so post-auth
redirects work in dev without disabling Validate.
Signed-off-by: Émile Ré <emile@probo.com>
When a reference name wraps to two lines, sibling cards in the
same grid row stayed shorter because MediaTile only sized to its
content. Fill the grid cell and grow the caption so peers match.
Signed-off-by: Émile Ré <emile@probo.com>
Vite only forwarded /graphql, so /initiate?continue=… fell through
to the SPA and the locale loader rewrote it to /en/initiate.
Match the host-root API routes (including query strings) so local
OAuth hits the Go backend.
Signed-off-by: Émile Ré <emile@probo.com>
Let signed-in visitors override the OS color scheme from
the account menu without persisting across reloads, and
keep themed logos in sync with the effective mode.
Signed-off-by: Émile Ré <emile@probo.com>
Long nav copy was squeezing the entity name into an
ellipsis inside max-w-5xl. Stack name over the tagline,
hide brand text below lg, and shorten the longest
topBar.nav strings so the brand stays readable.
Signed-off-by: Émile Ré <emile@probo.com>
Static lang=\"en\" in index.html left French UI declared as English
for assistive tech. Mirror the compliance portal by updating
document.documentElement.lang on init and when the locale changes.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
Chrome PrintToPDF now requests a structure tree and document
outline by default, with optional RenderConfig overrides. Add
lang="en" on the e-signature certificate template so /Lang is
emitted.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
Reject deletion while a campaign is fetching sources so workers are
not racing a removed record. All other statuses remain deletable.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
Drop the backend status gate on campaign delete and show delete in
the console whenever the user has delete permission, regardless of
whether the campaign is draft, in progress, or completed.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
Completed campaigns were immutable because delete only accepted draft
or cancelled status. Extend deletion to completed records and surface
delete in the console for that status.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
Removing junction rows before deleteRisk hid missing soft-delete
cleanup in e2e. Assert deleteRisk succeeds only after deleteDocument
clears mappings, and document links must be removed first.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
The regression test previously passed even when junction rows remained,
because unlink and deleteRisk masked missing soft-delete cleanup.
Query the risk documents connection before and after deleteDocument.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
Document soft delete cleared generated-document references but left
control, risk, and measure junction rows pointing at deleted documents.
That blocked risk deletion and made unlinkRisk fail when the document
was already gone.
Remove entity mappings in SoftDelete and BulkSoftDelete, drop mappings
before deleting a risk, tolerate missing documents when unlinking, and
backfill orphaned junction rows for soft-deleted documents.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
PKG users enroll in the browser at /enroll (or via
the menu bar icon), not through CLI install steps.
Shorten welcome and conclusion panes and drop path
inventories, MDM notes, and admin CLI setup.
Signed-off-by: Ludovic Vielle <ludovic@probo.com>
Pass/fail was the main device UI signal, but operators need
the agent's observed value. Expose a formatted value per
check, show current postures on the device page, and replace
the Postures tab with paginated report history grouped by
agent push time. Status stays in the model for later rulesets.
Signed-off-by: Ludovic Vielle <ludovic@probo.com>
Introduce make lint-shell / fmt-shell with shellcheck and
shfmt (-i 2 -ci -bn), normalize first-party scripts, and
document the new targets. Keep them out of make lint / fmt.
Signed-off-by: Ludovic Vielle <ludovic@probo.com>
Expose AUDIT_START_DATE and AUDIT_END_DATE on AuditOrderField
so list queries can paginate like valid_from and valid_until.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
Match valid_from and valid_until on audits and the console
date-only inputs for audit start and end.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
Store audit_start_date and audit_end_date as TIMESTAMP WITH
TIME ZONE. Alphabetize n8n audit field collections to satisfy
n8n-node lint.
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>