Skip to content

feat(datagrid): mask sensitive columns in the results grid - #587

Open
iamthenuggetman wants to merge 5 commits into
TabularisDB:mainfrom
iamthenuggetman:feat/column-masking
Open

feat(datagrid): mask sensitive columns in the results grid#587
iamthenuggetman wants to merge 5 commits into
TabularisDB:mainfrom
iamthenuggetman:feat/column-masking

Conversation

@iamthenuggetman

Copy link
Copy Markdown
Contributor

Closes #485

What

Columns whose name matches a sensitive pattern (password, email, token, ssn, …) now render as a •••••• placeholder in the results grid instead of the real value.

  • Per-cell reveal: masked cells show an eye button that reveals just that cell; a revealed cell gets an eye-off button to re-mask it
  • Per-column reveal: masked column headers show an eye toggle that reveals / re-masks the whole column
  • Edit guard: masked cells can't be edited (double-click, Enter, F2) until revealed, and the hover tooltip is suppressed so it can't leak the value
  • Reveal state is grid-local and resets when the result data changes

Masking is display-only: copy (⌘/Ctrl+C, context menu) and export keep the real values, as requested in the issue. Write-path anonymization for exports is tracked separately in #483.

Settings

New Settings → Privacy tab:

  • On/off toggle for masking (default: on)
  • Editable column-name patterns (one per line, case-insensitive substring match)
  • Per-connection include/exclude overrides as table.column entries — exclude wins over include, which wins over name patterns

Implementation

  • src/utils/columnMasking.ts — pattern/overrides matching logic
  • DataGrid.tsx / DataGridRow.tsx — masked rendering + reveal toggles
  • SettingsContext.tscolumnMaskingEnabled / columnMaskingPatterns / columnMaskingOverrides settings
  • PrivacyTab.tsx + tab registration in Settings.tsx
  • i18n strings for all 11 locales

Tests

  • 8 unit tests for the matching logic (tests/utils/columnMasking.test.ts)
  • 5 DataGrid tests: placeholder rendering, column reveal/re-mask, per-cell reveal/re-mask, copy keeps the real value, edit guard on masked cells
  • Full suite green (3443 tests), tsc -b and eslint clean

Tim McKeage and others added 3 commits August 1, 2026 11:34
Columns whose name matches a sensitive pattern (password, email, token,
…) render as a placeholder instead of the real value. A header eye
toggle reveals a whole column; a per-cell eye reveals just that cell.
Masked cells cannot be edited until revealed, and reveal state resets
when the result data changes.

Masking is display-only: copy and export keep the real values —
write-path anonymization is tracked separately in TabularisDB#483.

Adds a Settings → Privacy tab with an on/off toggle, editable name
patterns, and per-connection include/exclude overrides (table.column,
exclude wins over include and patterns).

Closes TabularisDB#485
# Conflicts:
#	src/components/ui/DataGrid.tsx
#	src/components/ui/DataGridRow.tsx
#	tests/components/ui/DataGrid.test.tsx
@debba

debba commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

First of all, I really like this feature. The display-only approach with per-cell and per-column reveal is exactly what #485 asked for, and the test coverage is appreciated.

Before merging I'd like to request a few changes, mostly about consistency with the rest of the app:

  1. Use the shared Select component. The Privacy tab introduces a plain native <select> with its own styling, while the rest of the settings UI uses the shared Select component. Please switch to that one so the look and behavior stay consistent.

  2. Tab position. In the settings sidebar I'd place Privacy right after Appearance instead of right after General.

  3. Per-connection overrides in the connection modal. Since the include/exclude overrides are per-connection, it should also be possible to manage them from a Privacy tab inside the connection modal, not only from the global settings. Please reuse what the settings tab already provides rather than duplicating it.

The core masking logic looks solid, so nothing to change there. Happy to merge once these points are addressed!

Tim McKeage added 2 commits August 5, 2026 11:33
- Privacy tab: use the shared Select component for the connection
  picker instead of a native select
- Settings sidebar: move Privacy after Appearance
- Connection modal: manage per-connection masking overrides from a
  Privacy tab (edit mode only — overrides are keyed by the saved
  connection id), reusing the extracted MaskingOverridesEditor shared
  with the settings tab
…umn-masking

# Conflicts:
#	src/components/modals/NewConnectionModal.tsx
@iamthenuggetman

Copy link
Copy Markdown
Contributor Author

thanks @debba i've made the requested tweaks and will be pushing shortly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat]: Mask sensitive columns in the results grid

2 participants