Introduce updateWorkspaceMemberSettings and clarify product (#19441)
## Summary Introduces a dedicated **metadata** mutation to update **standard (non-custom)** workspace member settings, moves profile-related UI to use it, and aligns **workspace member** record permissions with the rest of the CRM so users cannot escalate visibility via RLS by editing their own member record. ## Product behaviour ### Profile and appearance (standard fields) - Users can still update **their own** standard workspace member fields that the product exposes in **Settings / Profile** (e.g. name, locale, color scheme, avatar flow) via the new **`updateWorkspaceMemberSettings`** mutation. - The mutation returns a **boolean**; the app **merges** the updated fields into local state so the UI stays in sync without refetching the full workspace member record. - **Locale** changes also keep **`userWorkspace`** in sync when a locale is present in the payload (including from the workspace `updateOne` path when applicable). ### Custom fields on workspace members - The dedicated metadata mutation **rejects** any **custom** workspace member field (and unknown keys). Those updates must go through the normal **object** `updateOne` pipeline, which is subject to **object- and field-level** permissions like other records. But since we don't have object- and field-level permission configuration for system objects yet, this permission is derived from Workspace member settings permission. - **Workspace member** is no longer exempt from ORM permission validation for updates merely because it is a **system** object. Users who **do not** have workspace member access (e.g. no **Workspace members** settings permission and no equivalent broad settings access on the role) **cannot** use `updateOne` on `workspaceMember` to change **custom** (or other) fields on their own row—even though that row is used for RLS predicates. - This closes a path where someone could widen what they can see by writing to fields that drive row-level rules. ### Who can change another member - Updating **another** user’s workspace member still requires **Workspace members** (or equivalent) settings permission, consistent with admin tooling.
This commit is contained in:
@@ -7,11 +7,11 @@ import {
|
||||
import { useColorScheme } from '@/ui/theme/hooks/useColorScheme';
|
||||
import { resetJotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
|
||||
|
||||
const updateOneRecordMock = jest.fn();
|
||||
const mockUpdateWorkspaceMemberSettings = jest.fn();
|
||||
|
||||
jest.mock('@/object-record/hooks/useUpdateOneRecord', () => ({
|
||||
useUpdateOneRecord: () => ({
|
||||
updateOneRecord: updateOneRecordMock,
|
||||
jest.mock('@/settings/profile/hooks/useUpdateWorkspaceMemberSettings', () => ({
|
||||
useUpdateWorkspaceMemberSettings: () => ({
|
||||
updateWorkspaceMemberSettings: mockUpdateWorkspaceMemberSettings,
|
||||
}),
|
||||
}));
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||
import { useUpdateWorkspaceMemberSettings } from '@/settings/profile/hooks/useUpdateWorkspaceMemberSettings';
|
||||
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
|
||||
import { useCallback } from 'react';
|
||||
import { CoreObjectNameSingular } from 'twenty-shared/types';
|
||||
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
||||
import { persistedColorSchemeState } from '@/ui/theme/states/persistedColorSchemeState';
|
||||
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
|
||||
import { type ColorScheme } from '@/workspace-member/types/WorkspaceMember';
|
||||
@@ -18,7 +17,7 @@ export const useColorScheme = () => {
|
||||
currentWorkspaceMemberState,
|
||||
);
|
||||
|
||||
const { updateOneRecord } = useUpdateOneRecord();
|
||||
const { updateWorkspaceMemberSettings } = useUpdateWorkspaceMemberSettings();
|
||||
const setPersistedColorScheme = useSetAtomState(persistedColorSchemeState);
|
||||
|
||||
const colorScheme = currentWorkspaceMember?.colorScheme ?? 'System';
|
||||
@@ -38,10 +37,9 @@ export const useColorScheme = () => {
|
||||
colorScheme: value,
|
||||
};
|
||||
});
|
||||
await updateOneRecord({
|
||||
objectNameSingular: CoreObjectNameSingular.WorkspaceMember,
|
||||
idToUpdate: currentWorkspaceMember?.id,
|
||||
updateOneRecordInput: {
|
||||
await updateWorkspaceMemberSettings({
|
||||
workspaceMemberId: currentWorkspaceMember.id,
|
||||
update: {
|
||||
colorScheme: value,
|
||||
},
|
||||
});
|
||||
@@ -50,7 +48,7 @@ export const useColorScheme = () => {
|
||||
currentWorkspaceMember,
|
||||
setCurrentWorkspaceMember,
|
||||
setPersistedColorScheme,
|
||||
updateOneRecord,
|
||||
updateWorkspaceMemberSettings,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user