Commit Graph

4389 Commits

Author SHA1 Message Date
Cursor Agent
88eb340aba Use VCR cassette for PostHog driver test
Replace the PostHog driver unit test's local HTTP server with the same\nrecorder-backed test style used by the other access-review drivers.\n\nAdd a committed PostHog cassette under testdata so replay mode works\nwithout network access while keeping fixture coverage for role, MFA,\nand timestamp mapping expectations.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
2026-05-28 18:37:18 -07:00
Cursor Agent
4d1417b512 Add PostHog access review connector support
Introduce a PostHog access-review driver that lists organization\nmembers and maps role, MFA, and timestamp fields into account\nrecords.\n\nRegister PostHog as a builtin API-key connector provider and expose\nit through the connector provider enum so access-review source\ncreation can discover it.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
2026-05-28 18:37:18 -07:00
Cursor Agent
b493534545 Use k7 Metabase cassette fixture
Align the Metabase driver VCR test with the existing driver fixture
pattern by using a k7 Metabase host in the cassette and default test
instance URL.

This keeps cassette replay deterministic and consistent with the
expected environment naming used by other driver tests.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
2026-05-28 18:36:36 -07:00
Cursor Agent
0920785bdf Add Metabase access review source
Implement Metabase as a first-class access review connector backed by
GET /api/user, including account mapping and error handling in the
driver. Register the provider with API-key auth metadata and required
instance URL settings so connectors can be created and resolved
consistently.

Expose Metabase through the console GraphQL and UI flows by adding the
provider enum value, API-key extra setting field wiring, and source
label mapping. Add migration support for the connector_provider enum and
cover driver/provider behavior with focused tests.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
2026-05-28 18:36:36 -07:00
Cursor Agent
5ca1e369c0 Adopt VCR cassette style for Grafana tests
Refactor the Grafana driver test to use the shared recorder and VCR
helpers used by other access-review drivers.

This aligns the test with the existing cassette workflow and adds a
committed cassette fixture for deterministic replay.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
2026-05-28 18:35:02 -07:00
Cursor Agent
f5a632ffac Add Grafana access review connector support
Add Grafana as an access review connector-backed source.

This introduces a Grafana access-review driver, provider registration,
and connector settings for the Grafana base URL. It also wires the
new provider through GraphQL and access-review UI input mapping so
API-key connectors can be created from the product.

A connector_provider enum migration is included so Grafana can be
persisted in existing databases.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
2026-05-28 18:35:01 -07:00
Bryan Frimin
fcd7d68778 Fix wsl_v5 lint: add blank line between if blocks in createSignatureRequestInTx
Signed-off-by: Bryan Frimin <bryan@probo.com>
2026-05-28 18:19:37 -07:00
Bryan Frimin
65bfaa9f51 Cancel signature requests when a contract ends
When UpdateUser sets a contract end date that is already in the past,
the user can no longer fulfill outstanding signature requests. Delete
their still-pending requests as part of the same update so they stop
appearing as awaiting signatures.

Signed-off-by: Bryan Frimin <bryan@probo.com>
2026-05-28 18:12:40 -07:00
Bryan Frimin
1a8ca29264 Scope document signatures to the major version
A signature applies to a whole major: minor publishes keep it and the
export unions signatures across every minor of the major. The request
guard was scoped to a single minor, so re-requesting on a newer minor
(or twice on the same version) inserted duplicate rows and a signatory
appeared several times on the exported signature page.

Deduplicate by loading any existing signature across the major before
inserting, cancel still-pending requests from prior majors when a new
major is published, and restrict the export to active signatories
(comparing contract end dates against the current date). A migration
collapses the duplicate rows already in the table, preferring a signed
row over a pending one and then the most recent.

Signed-off-by: Bryan Frimin <bryan@probo.com>
2026-05-28 18:12:32 -07:00
Aurélien Sibiril
4efba328a6 Add Cursor third-party logo
Register the Cursor brand mark so the connector renders in the
access-review provider picker.

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-05-29 00:05:48 +02:00
Aurélien Sibiril
bd83799fdd Register Cursor access-review connector
Wire Cursor into the connector-provider registry as an API-key,
single-tenant connector using HTTP Basic auth, with no picker,
settings, or name resolver. Add the CURSOR enum value, its
migration, and the GraphQL enum binding so the provider is
accepted across the API surface.

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-05-29 00:05:48 +02:00
Aurélien Sibiril
427af88f3a Add Cursor access-review driver
Fetch team members from the Cursor Admin API (GET /teams/members)
and map them to access records. The endpoint is not paginated, so
a single request returns the whole team; removed members are
returned as inactive rather than dropped, and team owners are
flagged as admins.

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-05-29 00:05:48 +02:00
Aurélien Sibiril
0149ca4f55 Support HTTP Basic auth in API-key connections
Cursor's Admin API authenticates with the admin key as the HTTP
Basic auth username (empty password) and rejects Bearer tokens.
The API-key connection previously supported only Bearer and a
custom header (Anthropic's x-api-key); add a Basic-auth mode
selected by Registration.APIKeyBasicAuth, and reject providers
that set both it and APIKeyHeader.

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-05-29 00:05:48 +02:00
Cursor Agent
72c35a9967 Inline signature delete error check
Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
2026-05-28 14:58:01 -07:00
Cursor Agent
f7309c642a Cancel signature requests on deactivation
Disabling a profile now removes pending document signature requests tied to that signatory. This keeps inactive accounts from retaining signature work across manual, archived, and SCIM deactivation flows.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
2026-05-28 14:58:01 -07:00
Bryan Frimin
122bc02a23 Fix too much account on MS365 access review
Signed-off-by: Bryan Frimin <bryan@probo.com>
2026-05-28 14:56:54 -07:00
Bryan Frimin
0e1102e4c4 Release @probo/n8n-nodes-probo/v0.190.0
Signed-off-by: Bryan Frimin <bryan@probo.com>
2026-05-28 14:10:08 -07:00
Bryan Frimin
ada92790bc Release probod/v0.198.0
Signed-off-by: Bryan Frimin <bryan@probo.com>
2026-05-28 14:08:23 -07:00
Aurélien Sibiril
e663993882 Add Anthropic third-party logo
Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-05-28 22:33:29 +02:00
Aurélien Sibiril
83b48333d8 Register Anthropic access-review connector
Add the ANTHROPIC connector_provider enum value, its migration, and the
GraphQL enum binding, then register the provider as an API-key connector
that authenticates via x-api-key.

The probe URL is left empty because the shared connection probe cannot
send the required anthropic-version header and would misreport a valid
key; a dead key surfaces on the first member fetch instead.

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-05-28 22:33:29 +02:00
Aurélien Sibiril
50093c9d19 Add Anthropic access-review driver and resolver
The driver lists organization members through the Anthropic Admin API
(GET /v1/organizations/users) with cursor pagination, mapping the role
and the RFC 3339 added_at timestamp. The name resolver reads the
organization name from /v1/organizations/me; a non-2xx response (for
example a revoked key) yields no name rather than making the
source-name worker retry forever. Both send the required
anthropic-version header.

Add a VCR test helper that injects the key via x-api-key so the
cassette stays recordable, and strip x-api-key on save. The cassette
holds synthetic members covering the user, developer, and admin roles.

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-05-28 22:33:29 +02:00
Aurélien Sibiril
f6510e25a1 Support a custom API-key auth header in connections
The API-key connection always presented the key as Authorization:
Bearer. Some providers, notably Anthropic, require the key in a custom
header such as x-api-key and reject Bearer auth, returning 400 when
both headers are present.

Add an optional Header field on APIKeyConnection (empty preserves the
Bearer default for every existing provider) served by a small transport
that omits Authorization, plus a registry-declared APIKeyHeader so the
create-connector resolver wires the right scheme per provider.

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-05-28 22:33:29 +02:00
Aurélien Sibiril
e0c53e7a51 Name Heroku personal account without an API call
GET /teams/@personal 404s, which would loop the source-name worker the
same way a stale Sentry slug did. Short-circuit the personal-account
slug to a static name before any HTTP call.

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-05-28 22:22:46 +02:00
Aurélien Sibiril
e467060056 Allow empty team for the Heroku connector driver
The driver now runs in personal mode when no team is configured, so the
team_id-required guard would block solo accounts from ever building a
driver. Drop it and let an empty or personal-account slug flow through.

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-05-28 22:22:46 +02:00
Aurélien Sibiril
3b54a58d14 Offer Personal account in Heroku org picker
Heroku Teams are opt-in, so a solo account surfaces no options and the
picker used to dead-end at a free-text slug the user cannot fill. Always
append a synthetic Personal account entry so the picker offers personal
mode instead.

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-05-28 22:22:46 +02:00
Aurélien Sibiril
05fc9508ec Review solo Heroku accounts via app collaborators
A personal Heroku account has no Team, so GET /teams returns an empty
list and the team-members path has nothing to fetch. Solo accounts
grant access per app, so enumerate the user's personal apps and collect
each app's owner plus its collaborators, deduped by Heroku user ID.

An empty teamID (or the reserved personal-account slug) now selects this
personal mode. Factor the Range/Next-Range pagination shared by the
members, apps, and collaborators endpoints into herokuListAll.

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-05-28 22:22:46 +02:00
Bryan Frimin
558d40fb46 Style
Signed-off-by: Bryan Frimin <bryan@probo.com>
2026-05-28 12:41:50 -07:00
Bryan Frimin
bf4b3214f6 Style
Signed-off-by: Bryan Frimin <bryan@probo.com>
2026-05-28 12:36:45 -07:00
Bryan Frimin
0161b21120 Best effort connector delete
Signed-off-by: Bryan Frimin <bryan@probo.com>
2026-05-28 12:30:36 -07:00
Bryan Frimin
d579879707 Add tailscale driver
Signed-off-by: Bryan Frimin <bryan@probo.com>
2026-05-28 12:30:34 -07:00
Cursor Agent
dd547471e6 Disable role sorting in people list
The role order field is not supported on the GraphQL profile ordering
path, which makes role-based sorting fail at runtime.

Keep the role column visible for users who can manage roles, but render
it as a regular table header instead of a sortable one.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
2026-05-28 12:23:18 -07:00
Cursor Agent
8b6e9e420a Allow ordering profiles by email address
GraphQL profile ordering rejected EMAIL_ADDRESS because ProfileOrderField
did not expose this enum value in connect and console schemas.

Add EMAIL_ADDRESS to MembershipProfileOrderField and its validation list
so order input coercion accepts the value consistently. Extend
MembershipProfile cursor key encoding to support email ordering and avoid
runtime panics during pagination.

Update the MCP profile order enum to keep API surface definitions aligned
with the same ordering capability.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
2026-05-28 12:23:17 -07:00
Cursor Agent
29d8181b2c Add Global vendor country region
Allow vendor country selections to use a Global region alongside
existing country and EU values. The new value is accepted by backend
country-code validation, exposed through GraphQL and MCP schemas, and
shown in the shared country picker label set.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
2026-05-28 18:51:42 +00:00
Aurélien Sibiril
93d8d20dbf Surface stale Sentry slug in ListAccounts error
ListAccounts on a connector whose stored slug is no longer accessible
to its OAuth token currently returns "cannot fetch sentry members:
unexpected status 404" -- opaque, and indistinguishable from a real
Sentry outage. The campaign source-fetch worker records that string
verbatim as the customer-visible LastError, with no hint that the
connector itself needs reconnection.

queryMembers now returns a sentinel errSentryOrgNotAccessible on 404,
and ListAccounts wraps it with the slug and a directive to reconnect.
errors.Is preserves the chain so future callers can branch on the
permanent-config-failure case without string matching.

No auto-recovery: the only safe slug is one the customer explicitly
chose. Picking a different visible org would silently rebind the
source to the wrong tenant.

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-05-28 19:22:45 +02:00
Aurélien Sibiril
1844797b39 Stop source-name worker from looping on stale Sentry slug
The source-name worker re-claims any AccessSource whose name resolver
returns an error. kit/worker drains tasks in a tight inner loop per
tick, so a permanently-failing resolver hammers Sentry as fast as the
HTTP RTT allows -- in prod, ~5 errors/s for 12h+ on one stale slug.

A 404 from /api/0/organizations/{slug} means the stored slug is no
longer visible to the OAuth token (org renamed/deleted, membership
changed). Retrying cannot recover the name, so return ("", nil) like
the openai and intercom resolvers already do: the worker marks the
row synced, the flood stops, and the source keeps its generic name.

Other non-2xx (401/403/5xx) stay retryable so OAuth refresh and
transient outages still get another chance.

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-05-28 19:22:45 +02:00
Aurélien Sibiril
036cd3306e Reuse ListSentryOrganizations in Sentry driver
SentryDriver.resolveOrgSlug duplicated the same /organizations/?member=true
call already implemented in ListSentryOrganizations, which is consumed by
the OAuth org picker. Delegating to the shared helper prevents the two
call sites from drifting (response shape, header set, pagination) and
keeps the driver focused on member listing.

Pure refactor: no behavior change. Add an httptest-backed smoke test
covering the empty-stored-slug path end-to-end through ListAccounts so
the auto-discovery flow stays exercised after the refactor.

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-05-28 19:22:45 +02:00
Bryan Frimin
5e78b11f08 Release probod/v0.197.0
Signed-off-by: Bryan Frimin <bryan@probo.com>
2026-05-28 09:54:57 -07:00
Bryan Frimin
80be22fe8a Show SCIM error message
Signed-off-by: Bryan Frimin <bryan@probo.com>
2026-05-28 09:46:26 -07:00
Sacha Al Himdani
c78a713adf Refactor risks frontend to follow page arborescence conventions
- Split layout's monolithic query: each child route now owns its query
  via its own *PageLoader + *Page (overview/measures/documents/controls/
  obligations/scenarios).
- Rename tabs/RiskXTab.tsx -> <resource>/RiskXPage.tsx; drop UI-named
  tabs/ and dialogs/ folders.
- Move FormRiskDialog, PublishRiskListDialog and the extracted RiskRow
  into _components/ as named exports.
- Move risk form fragment ownership into FormRiskDialog: define
  FormRiskDialog_risk in the dialog and pass plain data to useRiskForm
  so spread sites colocate cleanly without disable comments.
- Align risk components with react-components.md naming: rename Relay
  fragments to ComponentName_typeName and replace 'type Props' aliases
  with 'interface ComponentNameProps'.
- Guard risk pages against null node and mutation errors: add
  __typename narrowing to every node(id) query, surface deleteRisk
  errors via toast, and resolve the confirm promise on error so the
  dialog no longer hangs.
- Replace deprecated useMutationWithToasts (FormRiskDialog) and
  useLazyLoadQuery (LinkScenarioDialog) with useMutation+useToast and
  useQueryLoader+usePreloadedQuery.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-05-28 15:02:09 +02:00
dependabot[bot]
361fc0f7bc Bump tmp from 0.2.5 to 0.2.7
Bumps [tmp](https://github.com/raszi/node-tmp) from 0.2.5 to 0.2.7.
- [Changelog](https://github.com/raszi/node-tmp/blob/master/CHANGELOG.md)
- [Commits](https://github.com/raszi/node-tmp/compare/v0.2.5...v0.2.7)

---
updated-dependencies:
- dependency-name: tmp
  dependency-version: 0.2.6
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-28 14:02:15 +02:00
Sacha Al Himdani
e6b40957ee Add invitingOrganizations field on viewer
Expose viewer.invitingOrganizations: [Organization!]! returning the
organizations that have a live pending invitation directed at the
current identity (accepted_at IS NULL AND expires_at > NOW()). The
list is rendered under a "Pending invitations" section on the
memberships page and in the organization selector dropdown, so a user
already signed in with an existing identity can see which
organizations have invited them without having to dig through their
inbox.

The new field is gated by iam:invitation:list against the viewer's
own identity, so it does not loosen authorization on Organization
elsewhere. E2E coverage validates the live-pending case, the
no-invitation and post-accept cases, and a multi-org scenario.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-05-28 13:42:29 +02:00
Bryan Frimin
f0b9acb748 Release probod/v0.196.1
Signed-off-by: Bryan Frimin <bryan@probo.com>
2026-05-27 19:27:13 -07:00
Bryan Frimin
b717e71d1a Fix bad state serialization
Signed-off-by: Bryan Frimin <bryan@probo.com>
2026-05-27 19:23:43 -07:00
Bryan Frimin
1a397b13bc Release @probo/cookie-banner/v0.7.0
Signed-off-by: Bryan Frimin <bryan@probo.com>
2026-05-27 18:20:56 -07:00
Bryan Frimin
31995aa0ca Release probod/v0.196.0
Signed-off-by: Bryan Frimin <bryan@probo.com>
2026-05-27 18:19:34 -07:00
Cursor Agent
6f4ac54a27 Expose bridge sync errors in SCIM API
Add a dedicated SCIMBridge syncError field to the Connect GraphQL API
and populate it from the core bridge model.

Update the connector cards to read bridge state and syncError directly
from the bridge object instead of inferring failures from event
history.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
2026-05-27 18:10:22 -07:00
Cursor Agent
83ce4286f8 Alias bridge event field to fix Relay build
Alias the connector card event selection so it does not conflict with
the SCIM event list fragment querying the same  field with
different arguments.

This resolves the Relay compilation failure in CI while keeping the
latest bridge error message available for the error-state callout.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
2026-05-27 18:10:22 -07:00
Cursor Agent
f02c3b88b7 Show bridge errors in connector cards
Display SCIM bridge state directly on Google Workspace and Microsoft
365 connector cards so admins can quickly identify failing bridges.

When a bridge is failed, render an inline error callout and surface the
latest provisioning event error message to make troubleshooting visible
without leaving the connector section.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
2026-05-27 18:10:22 -07:00
Cursor Agent
4d4f4fa526 Expose profile source in MCP users
Add a ProfileSource schema to the MCP specification and include source\nin the Profile response schema so MCP clients can distinguish\nmanual and SCIM-managed users.\n\nWire the source field in the Profile mapper so list, get, and\ncreate user responses return the persisted profile source.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>
2026-05-28 00:25:50 +00:00
Bryan Frimin
f40fae63b3 Release @probo/n8n-nodes-probo/v0.189.0
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-05-27 13:48:17 -07:00