From 4a276e3ef785930c520ea3ce8386577f5aafc5d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89mile=20R=C3=A9?= Date: Tue, 28 Jul 2026 17:03:52 +0200 Subject: [PATCH] Split inactive profile state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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é --- apps/console/src/_locales/en-US.json | 2 +- apps/console/src/_locales/fr-FR.json | 3 +- apps/console/src/hooks/graph/PeopleGraph.ts | 8 ++- .../iam/organizations/people/PersonPage.tsx | 2 +- .../people/_components/PeopleList.tsx | 3 +- .../people/_components/PeopleListItem.tsx | 9 +-- e2e/console/user_test.go | 2 +- .../document/getAllSignatures.operation.ts | 3 +- .../Probo/actions/user/listUsers.operation.ts | 3 +- pkg/cmd/user/list/list.go | 4 +- .../visitor/portal_access_service.go | 3 +- pkg/complianceportal/visitor/service.go | 1 + pkg/coredata/membership_profile.go | 52 ++++++++++++++++++ pkg/coredata/membership_profile_filter.go | 19 ++++--- pkg/coredata/migrations/20260728T143246Z.sql | 55 +++++++++++++++++++ pkg/coredata/profile_state.go | 39 +++++++++++-- pkg/iam/auth_service.go | 5 +- pkg/iam/organization_service.go | 32 ++++++++--- pkg/iam/saml/service.go | 3 +- pkg/iam/scim/service.go | 27 +++++---- pkg/iam/session_service.go | 8 +-- .../api/connect/v1/graphql/profile.graphql | 6 +- .../api/connect/v1/identity_resolvers.go | 4 ++ .../api/connect/v1/organization_resolvers.go | 4 ++ .../api/connect/v1/profile_resolvers.go | 2 +- .../console/v1/graphql/organization.graphql | 6 +- .../api/console/v1/organization_resolvers.go | 4 ++ pkg/server/api/mcp/v1/schema.resolvers.go | 4 ++ pkg/server/api/mcp/v1/specification.yaml | 12 +++- 29 files changed, 261 insertions(+), 64 deletions(-) create mode 100644 pkg/coredata/migrations/20260728T143246Z.sql diff --git a/apps/console/src/_locales/en-US.json b/apps/console/src/_locales/en-US.json index 0a18b3034..9d8bd3ccb 100644 --- a/apps/console/src/_locales/en-US.json +++ b/apps/console/src/_locales/en-US.json @@ -1371,7 +1371,7 @@ "columns": { "name": "Name", "status": "Status", "email": "Email", "role": "Role", "createdOn": "Created on" }, "empty": "No people", "searchPlaceholder": "Search people...", - "filters": { "allStatuses": "All statuses", "active": "Active", "inactive": "Inactive", "allRoles": "All roles", "allTypes": "All types" } + "filters": { "allStatuses": "All statuses", "pending": "Pending", "active": "Active", "deactivated": "Deactivated", "allRoles": "All roles", "allTypes": "All types" } }, "peopleListItem": { "messages": { "invitationSent": "Invitation sent successfully", "roleUpdated": "Role updated successfully", "archived": "Person archived successfully", "removed": "Person removed successfully" }, diff --git a/apps/console/src/_locales/fr-FR.json b/apps/console/src/_locales/fr-FR.json index 8b7e1f109..750f70b5b 100644 --- a/apps/console/src/_locales/fr-FR.json +++ b/apps/console/src/_locales/fr-FR.json @@ -2458,8 +2458,9 @@ "searchPlaceholder": "Rechercher des personnes...", "filters": { "allStatuses": "Tous les statuts", + "pending": "En attente", "active": "Actif", - "inactive": "Inactif", + "deactivated": "Désactivé", "allRoles": "Tous les rôles", "allTypes": "Tous les types" } diff --git a/apps/console/src/hooks/graph/PeopleGraph.ts b/apps/console/src/hooks/graph/PeopleGraph.ts index c9e1d36fe..884855bce 100644 --- a/apps/console/src/hooks/graph/PeopleGraph.ts +++ b/apps/console/src/hooks/graph/PeopleGraph.ts @@ -24,7 +24,7 @@ import { } from "react-relay"; import { graphql } from "relay-runtime"; -import type { PeopleGraphQuery } from "#/__generated__/core/PeopleGraphQuery.graphql"; +import type { PeopleGraphQuery, ProfileFilter } from "#/__generated__/core/PeopleGraphQuery.graphql"; /* eslint-disable relay/unused-fields */ @@ -57,11 +57,15 @@ export function usePeople( organizationId: string, { contractEnded }: { contractEnded?: boolean } = {}, ) { + const filter: ProfileFilter = contractEnded !== undefined + ? { contractEnded, states: ["ACTIVE", "PENDING"] } + : { states: ["ACTIVE", "PENDING"] }; + const data = useLazyLoadQuery( peopleQuery, { organizationId: organizationId, - filter: contractEnded !== undefined ? { contractEnded } : null, + filter, }, { fetchPolicy: "network-only" }, ); diff --git a/apps/console/src/pages/iam/organizations/people/PersonPage.tsx b/apps/console/src/pages/iam/organizations/people/PersonPage.tsx index be12c7f4e..2329cdb6a 100644 --- a/apps/console/src/pages/iam/organizations/people/PersonPage.tsx +++ b/apps/console/src/pages/iam/organizations/people/PersonPage.tsx @@ -139,7 +139,7 @@ export function PersonPage(props: { queryRef: PreloadedQuery }) ); }; - const canArchive = person.canDelete && person.source !== "SCIM" && person.state !== "INACTIVE"; + const canArchive = person.canDelete && person.source !== "SCIM" && person.state !== "DEACTIVATED"; const canRemove = person.canRemoveMember && person.source !== "SCIM"; return ( diff --git a/apps/console/src/pages/iam/organizations/people/_components/PeopleList.tsx b/apps/console/src/pages/iam/organizations/people/_components/PeopleList.tsx index 3b5a700b2..af0a9a189 100644 --- a/apps/console/src/pages/iam/organizations/people/_components/PeopleList.tsx +++ b/apps/console/src/pages/iam/organizations/people/_components/PeopleList.tsx @@ -231,8 +231,9 @@ export function PeopleList(props: { onValueChange={handleStateFilterChange} > + - +