From d989f802d537023732e4d59fceca6cb731220bb6 Mon Sep 17 00:00:00 2001 From: Devin Binnie <52460000+devinbinnie@users.noreply.github.com> Date: Mon, 17 Aug 2026 12:35:59 -0400 Subject: [PATCH] Disable TTL/grace period editing for server-derived attributes (#38001) * Disable TTL/grace period editing for server-derived attributes * FIx lint * Fix bug with dot menu --- .../session_attributes.scss | 2 + .../session_attributes.test.tsx | 16 ++-- .../session_attributes_dot_menu.test.tsx | 18 +++- .../session_attributes_dot_menu.tsx | 85 ++++++++++--------- .../session_attributes_table.test.tsx | 17 +++- .../session_attributes_table.tsx | 32 ++++--- webapp/channels/src/i18n/en.json | 1 + 7 files changed, 111 insertions(+), 60 deletions(-) diff --git a/webapp/channels/src/components/admin_console/session_attributes/session_attributes.scss b/webapp/channels/src/components/admin_console/session_attributes/session_attributes.scss index 68a70464c380..d8a10dd3f89b 100644 --- a/webapp/channels/src/components/admin_console/session_attributes/session_attributes.scss +++ b/webapp/channels/src/components/admin_console/session_attributes/session_attributes.scss @@ -121,9 +121,11 @@ border-radius: 4px; background: rgba(var(--center-channel-color-rgb), 0.08); color: rgba(var(--center-channel-color-rgb), 0.75); + cursor: pointer; font-size: 10px; font-weight: 600; text-transform: uppercase; + user-select: none; } .SessionAttributes__type-cell { diff --git a/webapp/channels/src/components/admin_console/session_attributes/session_attributes.test.tsx b/webapp/channels/src/components/admin_console/session_attributes/session_attributes.test.tsx index c409b1b9e8aa..907e99829ce6 100644 --- a/webapp/channels/src/components/admin_console/session_attributes/session_attributes.test.tsx +++ b/webapp/channels/src/components/admin_console/session_attributes/session_attributes.test.tsx @@ -59,7 +59,7 @@ function makeField(name: string, type: 'text' | 'select', sortOrder: number, ext } const representativeFields: UserPropertyField[] = [ - makeField('ip_address', 'text', 0, { + makeField('client_ip_address', 'text', 0, { display_name: 'Client IP', platforms: ['desktop', 'browser'], ttl_seconds: 300, @@ -212,9 +212,9 @@ describe('SessionAttributesPage', () => { await screen.findByText('Client IP'); - await userEvent.click(screen.getByTestId('session-attribute-dotmenu-session-ip_address')); + await userEvent.click(screen.getByTestId('session-attribute-dotmenu-session-client_ip_address')); await userEvent.hover(screen.getByRole('menuitem', {name: /Time-to-live/})); - await userEvent.click(await screen.findByTestId('session-attribute-ttl-option-session-ip_address-3600')); + await userEvent.click(await screen.findByTestId('session-attribute-ttl-option-session-client_ip_address-3600')); const saveButton = screen.getByRole('button', {name: /Save/}); expect(saveButton).toBeEnabled(); @@ -228,7 +228,7 @@ describe('SessionAttributesPage', () => { expect(patchPropertyField).toHaveBeenCalledWith( SESSION_ATTRIBUTES_GROUP_ID, SESSION_ATTRIBUTES_OBJECT_TYPE, - 'session-ip_address', + 'session-client_ip_address', {attrs: {ttl_seconds: 3600}}, ); }); @@ -255,9 +255,9 @@ describe('SessionAttributesPage', () => { await screen.findByText('Client IP'); expect(store.getState().views.admin.navigationBlock.blocked).toBe(false); - await userEvent.click(screen.getByTestId('session-attribute-dotmenu-session-ip_address')); + await userEvent.click(screen.getByTestId('session-attribute-dotmenu-session-client_ip_address')); await userEvent.hover(screen.getByRole('menuitem', {name: /Time-to-live/})); - await userEvent.click(await screen.findByTestId('session-attribute-ttl-option-session-ip_address-3600')); + await userEvent.click(await screen.findByTestId('session-attribute-ttl-option-session-client_ip_address-3600')); await waitFor(() => { expect(store.getState().views.admin.navigationBlock.blocked).toBe(true); @@ -277,9 +277,9 @@ describe('SessionAttributesPage', () => { await screen.findByText('Client IP'); - await userEvent.click(screen.getByTestId('session-attribute-dotmenu-session-ip_address')); + await userEvent.click(screen.getByTestId('session-attribute-dotmenu-session-client_ip_address')); await userEvent.hover(screen.getByRole('menuitem', {name: /Time-to-live/})); - await userEvent.click(await screen.findByTestId('session-attribute-ttl-option-session-ip_address-3600')); + await userEvent.click(await screen.findByTestId('session-attribute-ttl-option-session-client_ip_address-3600')); const stagedRow = screen.getAllByText('Client IP')[0].closest('tr') as HTMLElement; expect(within(stagedRow).getByTestId('session-attribute-ttl')).toHaveTextContent('1h'); diff --git a/webapp/channels/src/components/admin_console/session_attributes/session_attributes_dot_menu.test.tsx b/webapp/channels/src/components/admin_console/session_attributes/session_attributes_dot_menu.test.tsx index 11316de52133..a6cf8d518cd4 100644 --- a/webapp/channels/src/components/admin_console/session_attributes/session_attributes_dot_menu.test.tsx +++ b/webapp/channels/src/components/admin_console/session_attributes/session_attributes_dot_menu.test.tsx @@ -42,7 +42,7 @@ function makeField(name: string, extra: ExtraAttrs = {}): SessionAttributeField } as UserPropertyField; } -const enabledField = makeField('ip_address', { +const enabledField = makeField('client_ip_address', { display_name: 'Client IP', enabled: true, ttl_seconds: 300, @@ -56,6 +56,13 @@ const disabledField = makeField('vpn_active', { grace_period_seconds: 30, }); +const serverSourcedField = makeField('ip_address', { + display_name: 'IP Address', + enabled: true, + ttl_seconds: 300, + grace_period_seconds: 60, +}); + function renderMenu(field: SessionAttributeField, onStageChange = jest.fn()) { renderWithContext(