@libredb/studio 0.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +127 -0
- package/.cursorrules +426 -0
- package/.devin/wiki.json +143 -0
- package/.dockerignore +80 -0
- package/.env.example +159 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +49 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +29 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +57 -0
- package/.github/workflows/ci.yml +185 -0
- package/.github/workflows/codeql.yml +57 -0
- package/.github/workflows/docker-build-push.yml +118 -0
- package/.github/workflows/helm-release.yml +113 -0
- package/CLAUDE.md +265 -0
- package/CODE_OF_CONDUCT.md +124 -0
- package/CONTRIBUTING.md +154 -0
- package/Dockerfile +73 -0
- package/LICENSE +21 -0
- package/README.md +614 -0
- package/SECURITY.md +107 -0
- package/artifacthub-repo.yml +4 -0
- package/bun.lock +1714 -0
- package/bunfig.toml +3 -0
- package/charts/libredb-studio/.helmignore +11 -0
- package/charts/libredb-studio/Chart.lock +6 -0
- package/charts/libredb-studio/Chart.yaml +50 -0
- package/charts/libredb-studio/README.md +206 -0
- package/charts/libredb-studio/templates/NOTES.txt +59 -0
- package/charts/libredb-studio/templates/_helpers.tpl +135 -0
- package/charts/libredb-studio/templates/configmap.yaml +37 -0
- package/charts/libredb-studio/templates/deployment.yaml +184 -0
- package/charts/libredb-studio/templates/hpa.yaml +32 -0
- package/charts/libredb-studio/templates/ingress.yaml +41 -0
- package/charts/libredb-studio/templates/networkpolicy.yaml +50 -0
- package/charts/libredb-studio/templates/pdb.yaml +18 -0
- package/charts/libredb-studio/templates/pvc.yaml +23 -0
- package/charts/libredb-studio/templates/secret.yaml +30 -0
- package/charts/libredb-studio/templates/seed-configmap.yaml +11 -0
- package/charts/libredb-studio/templates/service.yaml +22 -0
- package/charts/libredb-studio/templates/serviceaccount.yaml +13 -0
- package/charts/libredb-studio/values.schema.json +246 -0
- package/charts/libredb-studio/values.yaml +286 -0
- package/components.json +22 -0
- package/conductor/code_styleguides/typescript.md +43 -0
- package/conductor/product-guidelines.md +43 -0
- package/conductor/product.md +3 -0
- package/conductor/setup_state.json +1 -0
- package/conductor/tech-stack.md +39 -0
- package/conductor/tracks/enhance_postgres_monitoring_20251227/metadata.json +8 -0
- package/conductor/tracks/enhance_postgres_monitoring_20251227/plan.md +44 -0
- package/conductor/tracks/enhance_postgres_monitoring_20251227/spec.md +31 -0
- package/conductor/tracks.md +8 -0
- package/conductor/workflow.md +333 -0
- package/database-compose.yml +55 -0
- package/docker/postgres-init/01-extensions.sql +10 -0
- package/docker/postgres-init/02-sample-data.sql +585 -0
- package/docker/postgres.yml +68 -0
- package/docker-compose.yml +38 -0
- package/docs/AI_PLAN.md +74 -0
- package/docs/API_DOCS.md +875 -0
- package/docs/ARCHITECTURE.md +218 -0
- package/docs/DATABASE_PROVIDERS.md +358 -0
- package/docs/FEATURES.md +116 -0
- package/docs/HELM_CHART.md +252 -0
- package/docs/LOGIN_PAGE.md +178 -0
- package/docs/MONACO_EDITOR_PERFORMANCE.md +315 -0
- package/docs/OIDC_ARCH.md +681 -0
- package/docs/OIDC_SETUP.md +322 -0
- package/docs/POSTGRES_METRICS.md +516 -0
- package/docs/QUERY_OPTIMIZATION.md +370 -0
- package/docs/SEED_CONNECTIONS.md +468 -0
- package/docs/SQL_ALIAS_COMPLETION.md +190 -0
- package/docs/STORAGE_ARCHITECTURE.md +565 -0
- package/docs/STORAGE_QUICK_SETUP.md +419 -0
- package/docs/TECHNICAL_PLAN.md +36 -0
- package/docs/THEMING.md +345 -0
- package/docs/adding-a-new-database-provider.md +642 -0
- package/docs/backlogs/000-PLATFORM_DATA_SYNC_DATABASE.md +360 -0
- package/docs/backlogs/001-INLINE_DATA_EDITING.md +118 -0
- package/docs/backlogs/002-DATA_IMPORT.md +215 -0
- package/docs/backlogs/003-QUERY_TIME_MACHINE.md +183 -0
- package/docs/backlogs/004-AI_DATA_STORYTELLER.md +292 -0
- package/docs/backlogs/005-QUERY_PLAYGROUND.md +352 -0
- package/docs/backlogs/006-DATA_MASKING.md +418 -0
- package/docs/enterprise-features.md +718 -0
- package/docs/kubernetes-helm-chart-artifacthub-plan.md +803 -0
- package/docs/medium-koyeb-article-en.md +215 -0
- package/docs/plans/test-plans.md +445 -0
- package/docs/releases/RELEASE.V0.3.0.md +22 -0
- package/docs/releases/RELEASE.V0.4.0.md +154 -0
- package/docs/releases/RELEASE.V0.5.0.md +252 -0
- package/docs/releases/RELEASE_v0.5.6.md +145 -0
- package/docs/releases/RELEASE_v0.6.1.md +303 -0
- package/docs/releases/RELEASE_v0.6.7.md +292 -0
- package/docs/releases/RELEASE_v0.7.0.md +332 -0
- package/docs/releases/RELEASE_v0.8.0.md +521 -0
- package/docs/sampledb/titanic.sql +1379 -0
- package/docs/superpowers/plans/2026-03-25-seed-connections.md +1362 -0
- package/docs/superpowers/specs/2026-03-25-seed-connections-design.md +590 -0
- package/e2e/admin-dashboard.spec.ts +64 -0
- package/e2e/connection-management.spec.ts +58 -0
- package/e2e/export.spec.ts +34 -0
- package/e2e/login.spec.ts +85 -0
- package/e2e/query-execution.spec.ts +35 -0
- package/e2e/tab-management.spec.ts +64 -0
- package/eslint.config.mjs +28 -0
- package/fly.toml +43 -0
- package/next.config.ts +32 -0
- package/package.json +130 -0
- package/playwright.config.ts +34 -0
- package/postcss.config.mjs +7 -0
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/file.svg +1 -0
- package/public/globe.svg +1 -0
- package/public/logo.svg +32 -0
- package/public/next.svg +1 -0
- package/public/screenshots/code-generator.png +0 -0
- package/public/screenshots/connection-modal.png +0 -0
- package/public/screenshots/data-profiler.png +0 -0
- package/public/screenshots/erd-diagram.png +0 -0
- package/public/screenshots/hero-editor.png +0 -0
- package/public/screenshots/nl2sql.png +0 -0
- package/public/vercel.svg +1 -0
- package/public/window.svg +1 -0
- package/render.yaml +58 -0
- package/scripts/merge-lcov.mjs +239 -0
- package/sonar-project.properties +16 -0
- package/src/app/admin/error.tsx +46 -0
- package/src/app/admin/page.tsx +10 -0
- package/src/app/api/admin/audit/route.ts +52 -0
- package/src/app/api/admin/fleet-health/route.ts +81 -0
- package/src/app/api/ai/autopilot/route.ts +105 -0
- package/src/app/api/ai/chat/route.ts +132 -0
- package/src/app/api/ai/describe-schema/route.ts +52 -0
- package/src/app/api/ai/explain/route.ts +86 -0
- package/src/app/api/ai/impact/route.ts +97 -0
- package/src/app/api/ai/index-advisor/route.ts +98 -0
- package/src/app/api/ai/nl2sql/route.ts +87 -0
- package/src/app/api/ai/query-safety/route.ts +87 -0
- package/src/app/api/auth/login/route.ts +62 -0
- package/src/app/api/auth/logout/route.ts +25 -0
- package/src/app/api/auth/me/route.ts +10 -0
- package/src/app/api/auth/oidc/callback/route.ts +82 -0
- package/src/app/api/auth/oidc/login/route.ts +43 -0
- package/src/app/api/connections/managed/route.ts +35 -0
- package/src/app/api/db/cancel/route.ts +42 -0
- package/src/app/api/db/disconnect/route.ts +28 -0
- package/src/app/api/db/health/route.ts +49 -0
- package/src/app/api/db/maintenance/route.ts +72 -0
- package/src/app/api/db/monitoring/route.ts +62 -0
- package/src/app/api/db/multi-query/route.ts +116 -0
- package/src/app/api/db/pool-stats/route.ts +37 -0
- package/src/app/api/db/profile/route.ts +144 -0
- package/src/app/api/db/provider-meta/route.ts +49 -0
- package/src/app/api/db/query/route.ts +50 -0
- package/src/app/api/db/schema/route.ts +47 -0
- package/src/app/api/db/schema-snapshot/route.ts +42 -0
- package/src/app/api/db/test-connection/route.ts +55 -0
- package/src/app/api/db/transaction/route.ts +111 -0
- package/src/app/api/storage/[collection]/route.ts +67 -0
- package/src/app/api/storage/config/route.ts +17 -0
- package/src/app/api/storage/migrate/route.ts +45 -0
- package/src/app/api/storage/route.ts +32 -0
- package/src/app/error.tsx +49 -0
- package/src/app/global-error.tsx +55 -0
- package/src/app/globals.css +146 -0
- package/src/app/icon.svg +42 -0
- package/src/app/layout.tsx +34 -0
- package/src/app/login/login-form.tsx +301 -0
- package/src/app/login/page.tsx +11 -0
- package/src/app/monitoring/page.tsx +8 -0
- package/src/app/not-found.tsx +29 -0
- package/src/app/page.tsx +5 -0
- package/src/components/AIAutopilotPanel.tsx +238 -0
- package/src/components/CodeGenerator.tsx +271 -0
- package/src/components/CommandPalette.tsx +227 -0
- package/src/components/ConnectionModal.tsx +759 -0
- package/src/components/CreateTableModal.tsx +281 -0
- package/src/components/DataCharts.tsx +962 -0
- package/src/components/DataImportModal.tsx +582 -0
- package/src/components/DataProfiler.tsx +335 -0
- package/src/components/DatabaseDocs.tsx +251 -0
- package/src/components/MaskingSettings.tsx +414 -0
- package/src/components/MobileNav.tsx +50 -0
- package/src/components/NL2SQLPanel.tsx +281 -0
- package/src/components/PivotTable.tsx +257 -0
- package/src/components/QueryEditor.tsx +760 -0
- package/src/components/QueryHistory.tsx +344 -0
- package/src/components/QuerySafetyDialog.tsx +290 -0
- package/src/components/ResultsGrid.tsx +644 -0
- package/src/components/SaveQueryModal.tsx +104 -0
- package/src/components/SavedQueries.tsx +128 -0
- package/src/components/SchemaDiagram.tsx +473 -0
- package/src/components/SchemaDiff.tsx +473 -0
- package/src/components/SnapshotTimeline.tsx +116 -0
- package/src/components/Studio.tsx +639 -0
- package/src/components/TestDataGenerator.tsx +261 -0
- package/src/components/VisualExplain.tsx +820 -0
- package/src/components/admin/AdminDashboard.tsx +163 -0
- package/src/components/admin/tabs/AuditTab.tsx +531 -0
- package/src/components/admin/tabs/MonitoringEmbed.tsx +11 -0
- package/src/components/admin/tabs/OperationsTab.tsx +646 -0
- package/src/components/admin/tabs/OverviewTab.tsx +1328 -0
- package/src/components/admin/tabs/SecurityTab.tsx +284 -0
- package/src/components/community-section.tsx +92 -0
- package/src/components/icons/db-icons.tsx +84 -0
- package/src/components/libredb-logo.tsx +61 -0
- package/src/components/monitoring/MonitoringDashboard.tsx +345 -0
- package/src/components/monitoring/tabs/MetricChart.tsx +82 -0
- package/src/components/monitoring/tabs/OverviewTab.tsx +263 -0
- package/src/components/monitoring/tabs/PerformanceTab.tsx +254 -0
- package/src/components/monitoring/tabs/PoolTab.tsx +174 -0
- package/src/components/monitoring/tabs/QueriesTab.tsx +287 -0
- package/src/components/monitoring/tabs/SessionsTab.tsx +316 -0
- package/src/components/monitoring/tabs/StorageTab.tsx +335 -0
- package/src/components/monitoring/tabs/TablesTab.tsx +300 -0
- package/src/components/results-grid/ResultCard.tsx +111 -0
- package/src/components/results-grid/RowDetailSheet.tsx +178 -0
- package/src/components/results-grid/StatsBar.tsx +201 -0
- package/src/components/results-grid/index.ts +1 -0
- package/src/components/results-grid/utils.ts +23 -0
- package/src/components/schema-explorer/ColumnList.tsx +53 -0
- package/src/components/schema-explorer/SchemaExplorer.tsx +182 -0
- package/src/components/schema-explorer/TableItem.tsx +210 -0
- package/src/components/schema-explorer/index.ts +1 -0
- package/src/components/sidebar/ConnectionItem.tsx +105 -0
- package/src/components/sidebar/ConnectionsList.tsx +62 -0
- package/src/components/sidebar/Sidebar.tsx +130 -0
- package/src/components/sidebar/index.ts +2 -0
- package/src/components/studio/BottomPanel.tsx +286 -0
- package/src/components/studio/QueryToolbar.tsx +180 -0
- package/src/components/studio/StudioDesktopHeader.tsx +114 -0
- package/src/components/studio/StudioMobileHeader.tsx +340 -0
- package/src/components/studio/StudioTabBar.tsx +82 -0
- package/src/components/studio/index.ts +5 -0
- package/src/components/ui/accordion.tsx +66 -0
- package/src/components/ui/alert-dialog.tsx +157 -0
- package/src/components/ui/alert.tsx +66 -0
- package/src/components/ui/aspect-ratio.tsx +11 -0
- package/src/components/ui/avatar.tsx +53 -0
- package/src/components/ui/badge.tsx +46 -0
- package/src/components/ui/breadcrumb.tsx +109 -0
- package/src/components/ui/button-group.tsx +83 -0
- package/src/components/ui/button.tsx +60 -0
- package/src/components/ui/calendar.tsx +216 -0
- package/src/components/ui/card.tsx +92 -0
- package/src/components/ui/carousel.tsx +241 -0
- package/src/components/ui/chart.tsx +357 -0
- package/src/components/ui/checkbox.tsx +32 -0
- package/src/components/ui/collapsible.tsx +33 -0
- package/src/components/ui/command.tsx +184 -0
- package/src/components/ui/context-menu.tsx +252 -0
- package/src/components/ui/dialog.tsx +143 -0
- package/src/components/ui/drawer.tsx +135 -0
- package/src/components/ui/dropdown-menu.tsx +257 -0
- package/src/components/ui/empty.tsx +104 -0
- package/src/components/ui/field.tsx +248 -0
- package/src/components/ui/form.tsx +167 -0
- package/src/components/ui/hover-card.tsx +44 -0
- package/src/components/ui/input-group.tsx +170 -0
- package/src/components/ui/input-otp.tsx +77 -0
- package/src/components/ui/input.tsx +21 -0
- package/src/components/ui/item.tsx +193 -0
- package/src/components/ui/kbd.tsx +28 -0
- package/src/components/ui/label.tsx +24 -0
- package/src/components/ui/menubar.tsx +276 -0
- package/src/components/ui/navigation-menu.tsx +168 -0
- package/src/components/ui/pagination.tsx +127 -0
- package/src/components/ui/popover.tsx +48 -0
- package/src/components/ui/progress.tsx +31 -0
- package/src/components/ui/radio-group.tsx +45 -0
- package/src/components/ui/resizable.tsx +56 -0
- package/src/components/ui/scroll-area.tsx +58 -0
- package/src/components/ui/select.tsx +187 -0
- package/src/components/ui/separator.tsx +28 -0
- package/src/components/ui/sheet.tsx +139 -0
- package/src/components/ui/sidebar.tsx +726 -0
- package/src/components/ui/skeleton.tsx +13 -0
- package/src/components/ui/slider.tsx +63 -0
- package/src/components/ui/sonner.tsx +40 -0
- package/src/components/ui/spinner.tsx +16 -0
- package/src/components/ui/switch.tsx +31 -0
- package/src/components/ui/table.tsx +116 -0
- package/src/components/ui/tabs.tsx +66 -0
- package/src/components/ui/textarea.tsx +18 -0
- package/src/components/ui/toggle-group.tsx +83 -0
- package/src/components/ui/toggle.tsx +47 -0
- package/src/components/ui/tooltip.tsx +61 -0
- package/src/exports/components.ts +15 -0
- package/src/exports/index.ts +4 -0
- package/src/exports/providers.ts +4 -0
- package/src/exports/types.ts +26 -0
- package/src/hooks/use-ai-chat.ts +182 -0
- package/src/hooks/use-all-connections.ts +66 -0
- package/src/hooks/use-api-call.ts +71 -0
- package/src/hooks/use-auth.ts +51 -0
- package/src/hooks/use-connection-form.ts +349 -0
- package/src/hooks/use-connection-manager.ts +169 -0
- package/src/hooks/use-connection-payload.ts +15 -0
- package/src/hooks/use-inline-editing.ts +109 -0
- package/src/hooks/use-mobile.ts +20 -0
- package/src/hooks/use-monitoring-data.ts +270 -0
- package/src/hooks/use-provider-metadata.ts +62 -0
- package/src/hooks/use-query-execution.ts +478 -0
- package/src/hooks/use-storage-sync.ts +259 -0
- package/src/hooks/use-tab-manager.ts +231 -0
- package/src/hooks/use-toast.ts +20 -0
- package/src/hooks/use-transaction-control.ts +64 -0
- package/src/lib/api/error-codes.ts +30 -0
- package/src/lib/api/errors.ts +236 -0
- package/src/lib/api/with-error-handler.ts +41 -0
- package/src/lib/audit.ts +105 -0
- package/src/lib/auth.ts +87 -0
- package/src/lib/connection-string-parser.ts +172 -0
- package/src/lib/data-masking.ts +385 -0
- package/src/lib/db/base-provider.ts +325 -0
- package/src/lib/db/errors.ts +317 -0
- package/src/lib/db/factory.ts +324 -0
- package/src/lib/db/index.ts +123 -0
- package/src/lib/db/providers/document/index.ts +6 -0
- package/src/lib/db/providers/document/mongodb.ts +992 -0
- package/src/lib/db/providers/keyvalue/redis.ts +554 -0
- package/src/lib/db/providers/sql/index.ts +11 -0
- package/src/lib/db/providers/sql/mssql.ts +1065 -0
- package/src/lib/db/providers/sql/mysql.ts +978 -0
- package/src/lib/db/providers/sql/oracle.ts +1044 -0
- package/src/lib/db/providers/sql/postgres.ts +1179 -0
- package/src/lib/db/providers/sql/sql-base.ts +174 -0
- package/src/lib/db/providers/sql/sqlite.ts +721 -0
- package/src/lib/db/types.ts +437 -0
- package/src/lib/db/utils/pool-manager.ts +287 -0
- package/src/lib/db/utils/query-limiter.ts +239 -0
- package/src/lib/db-ui-config.ts +86 -0
- package/src/lib/editor/mongodb-completions.ts +172 -0
- package/src/lib/editor/sql-completions.ts +280 -0
- package/src/lib/llm/base-provider.ts +117 -0
- package/src/lib/llm/factory.ts +102 -0
- package/src/lib/llm/index.ts +90 -0
- package/src/lib/llm/providers/custom.ts +181 -0
- package/src/lib/llm/providers/gemini.ts +126 -0
- package/src/lib/llm/providers/ollama.ts +154 -0
- package/src/lib/llm/providers/openai.ts +146 -0
- package/src/lib/llm/types.ts +173 -0
- package/src/lib/llm/utils/config.ts +187 -0
- package/src/lib/llm/utils/retry.ts +119 -0
- package/src/lib/llm/utils/streaming.ts +202 -0
- package/src/lib/logger.ts +127 -0
- package/src/lib/monitoring-thresholds.ts +44 -0
- package/src/lib/oidc.ts +262 -0
- package/src/lib/query-generators.ts +61 -0
- package/src/lib/schema-diff/diff-engine.ts +273 -0
- package/src/lib/schema-diff/migration-generator.ts +208 -0
- package/src/lib/schema-diff/types.ts +55 -0
- package/src/lib/seed/config-loader.ts +79 -0
- package/src/lib/seed/connection-filter.ts +49 -0
- package/src/lib/seed/credential-resolver.ts +62 -0
- package/src/lib/seed/index.ts +40 -0
- package/src/lib/seed/resolve-connection.ts +57 -0
- package/src/lib/seed/types.ts +69 -0
- package/src/lib/sql/alias-extractor.ts +267 -0
- package/src/lib/sql/index.ts +8 -0
- package/src/lib/sql/statement-splitter.ts +167 -0
- package/src/lib/sql/types.ts +40 -0
- package/src/lib/ssh/tunnel.ts +142 -0
- package/src/lib/storage/factory.ts +84 -0
- package/src/lib/storage/index.ts +14 -0
- package/src/lib/storage/local-storage.ts +99 -0
- package/src/lib/storage/providers/postgres.ts +225 -0
- package/src/lib/storage/providers/sqlite.ts +153 -0
- package/src/lib/storage/storage-facade.ts +272 -0
- package/src/lib/storage/types.ts +75 -0
- package/src/lib/time-series-buffer.ts +58 -0
- package/src/lib/types.ts +173 -0
- package/src/lib/utils.ts +6 -0
- package/src/proxy.ts +104 -0
- package/src/types/db-drivers.d.ts +23 -0
- package/src/types/html2canvas.d.ts +9 -0
- package/tests/api/admin/audit.test.ts +178 -0
- package/tests/api/admin/fleet-health.test.ts +183 -0
- package/tests/api/ai/autopilot.test.ts +174 -0
- package/tests/api/ai/chat.test.ts +250 -0
- package/tests/api/ai/describe-schema.test.ts +266 -0
- package/tests/api/ai/explain.test.ts +199 -0
- package/tests/api/ai/impact.test.ts +168 -0
- package/tests/api/ai/index-advisor.test.ts +171 -0
- package/tests/api/ai/nl2sql.test.ts +202 -0
- package/tests/api/ai/query-safety.test.ts +196 -0
- package/tests/api/auth/login.test.ts +170 -0
- package/tests/api/auth/logout.test.ts +140 -0
- package/tests/api/auth/me.test.ts +73 -0
- package/tests/api/auth/oidc-callback.test.ts +215 -0
- package/tests/api/auth/oidc-login.test.ts +127 -0
- package/tests/api/db/cancel.test.ts +198 -0
- package/tests/api/db/disconnect.test.ts +124 -0
- package/tests/api/db/health.test.ts +222 -0
- package/tests/api/db/maintenance.test.ts +263 -0
- package/tests/api/db/monitoring.test.ts +221 -0
- package/tests/api/db/multi-query.test.ts +316 -0
- package/tests/api/db/pool-stats.test.ts +135 -0
- package/tests/api/db/profile.test.ts +330 -0
- package/tests/api/db/provider-meta.test.ts +193 -0
- package/tests/api/db/query.test.ts +314 -0
- package/tests/api/db/schema-snapshot.test.ts +170 -0
- package/tests/api/db/schema.test.ts +191 -0
- package/tests/api/db/test-connection.test.ts +185 -0
- package/tests/api/db/transaction.test.ts +314 -0
- package/tests/api/proxy.test.ts +191 -0
- package/tests/api/seed/managed-route.test.ts +113 -0
- package/tests/api/storage/config.test.ts +42 -0
- package/tests/api/storage/storage-routes.test.ts +309 -0
- package/tests/components/AIAutopilotPanel.test.tsx +756 -0
- package/tests/components/AdminPage.test.tsx +33 -0
- package/tests/components/CodeGenerator.test.tsx +182 -0
- package/tests/components/CommandPalette.test.tsx +428 -0
- package/tests/components/CommunitySection.test.tsx +91 -0
- package/tests/components/ConnectionModal.mobile.test.tsx +284 -0
- package/tests/components/ConnectionModal.test.tsx +570 -0
- package/tests/components/CreateTableModal.test.tsx +383 -0
- package/tests/components/DataCharts.test.tsx +739 -0
- package/tests/components/DataImportModal.test.tsx +751 -0
- package/tests/components/DataProfiler.test.tsx +589 -0
- package/tests/components/DatabaseDocs.test.tsx +353 -0
- package/tests/components/LoginPage.test.tsx +163 -0
- package/tests/components/LoginPageOIDC.test.tsx +92 -0
- package/tests/components/MaskingSettings.test.tsx +498 -0
- package/tests/components/MobileNav.test.tsx +30 -0
- package/tests/components/MonitoringPage.test.tsx +32 -0
- package/tests/components/NL2SQLPanel.test.tsx +621 -0
- package/tests/components/Page.test.tsx +33 -0
- package/tests/components/PivotTable.test.tsx +350 -0
- package/tests/components/QueryEditor.test.tsx +1730 -0
- package/tests/components/QueryHistory.test.tsx +572 -0
- package/tests/components/QuerySafetyDialog.test.tsx +586 -0
- package/tests/components/ResultsGrid.test.tsx +804 -0
- package/tests/components/RootLayout.test.tsx +83 -0
- package/tests/components/SaveQueryModal.test.tsx +25 -0
- package/tests/components/SavedQueries.test.tsx +43 -0
- package/tests/components/SchemaDiagram.test.tsx +1034 -0
- package/tests/components/SchemaDiff.test.tsx +906 -0
- package/tests/components/SnapshotTimeline.test.tsx +174 -0
- package/tests/components/Studio.test.tsx +1030 -0
- package/tests/components/TestDataGenerator.test.tsx +291 -0
- package/tests/components/VisualExplain.test.tsx +704 -0
- package/tests/components/admin/AdminDashboard.test.tsx +205 -0
- package/tests/components/admin/AuditTab.test.tsx +220 -0
- package/tests/components/admin/MonitoringEmbed.test.tsx +58 -0
- package/tests/components/admin/OperationsTab.test.tsx +975 -0
- package/tests/components/admin/OverviewTab.test.tsx +254 -0
- package/tests/components/admin/SecurityTab.test.tsx +467 -0
- package/tests/components/monitoring/MetricChart.test.tsx +111 -0
- package/tests/components/monitoring/MonitoringDashboard.test.tsx +259 -0
- package/tests/components/monitoring/OverviewTab.test.tsx +78 -0
- package/tests/components/monitoring/PerformanceTab.test.tsx +87 -0
- package/tests/components/monitoring/PoolTab.test.tsx +42 -0
- package/tests/components/monitoring/QueriesTab.test.tsx +80 -0
- package/tests/components/monitoring/SessionsTab.test.tsx +154 -0
- package/tests/components/monitoring/StorageTab.test.tsx +127 -0
- package/tests/components/monitoring/TablesTab.test.tsx +153 -0
- package/tests/components/results-grid/ResultCard.test.tsx +105 -0
- package/tests/components/results-grid/RowDetailSheet.test.tsx +308 -0
- package/tests/components/results-grid/StatsBar.test.tsx +162 -0
- package/tests/components/schema-explorer/ColumnList.test.tsx +151 -0
- package/tests/components/schema-explorer/SchemaExplorer.test.tsx +461 -0
- package/tests/components/schema-explorer/TableItem.test.tsx +415 -0
- package/tests/components/sidebar/ConnectionItem.test.tsx +201 -0
- package/tests/components/sidebar/ConnectionsList.test.tsx +176 -0
- package/tests/components/sidebar/Sidebar.test.tsx +187 -0
- package/tests/components/studio/BottomPanel.test.tsx +383 -0
- package/tests/components/studio/QueryToolbar.test.tsx +321 -0
- package/tests/components/studio/StudioDesktopHeader.test.tsx +377 -0
- package/tests/components/studio/StudioMobileHeader.test.tsx +198 -0
- package/tests/components/studio/StudioTabBar.test.tsx +331 -0
- package/tests/fixtures/connections.ts +96 -0
- package/tests/fixtures/masking-configs.ts +86 -0
- package/tests/fixtures/query-results.ts +71 -0
- package/tests/fixtures/schemas.ts +64 -0
- package/tests/fixtures/seed-connections/invalid-config.yaml +7 -0
- package/tests/fixtures/seed-connections/minimal-config.yaml +8 -0
- package/tests/fixtures/seed-connections/mixed-credentials.yaml +23 -0
- package/tests/fixtures/seed-connections/multi-role-config.yaml +30 -0
- package/tests/fixtures/seed-connections/valid-config.json +15 -0
- package/tests/fixtures/seed-connections/valid-config.yaml +51 -0
- package/tests/helpers/mock-fetch.ts +59 -0
- package/tests/helpers/mock-monaco.ts +112 -0
- package/tests/helpers/mock-navigation.ts +28 -0
- package/tests/helpers/mock-next.ts +80 -0
- package/tests/helpers/mock-provider.ts +133 -0
- package/tests/helpers/mock-sonner.ts +29 -0
- package/tests/helpers/render-with-providers.tsx +19 -0
- package/tests/hooks/use-ai-chat.test.ts +600 -0
- package/tests/hooks/use-auth.test.ts +371 -0
- package/tests/hooks/use-connection-form.test.ts +743 -0
- package/tests/hooks/use-connection-manager.test.ts +466 -0
- package/tests/hooks/use-inline-editing.test.ts +321 -0
- package/tests/hooks/use-mobile.test.ts +177 -0
- package/tests/hooks/use-monitoring-data.test.ts +819 -0
- package/tests/hooks/use-provider-metadata.test.ts +228 -0
- package/tests/hooks/use-query-execution.test.ts +1212 -0
- package/tests/hooks/use-tab-manager.test.ts +756 -0
- package/tests/hooks/use-toast.test.ts +74 -0
- package/tests/hooks/use-transaction-control.test.ts +211 -0
- package/tests/integration/db/mongodb-provider.test.ts +698 -0
- package/tests/integration/db/mssql-provider.test.ts +840 -0
- package/tests/integration/db/mysql-provider.test.ts +872 -0
- package/tests/integration/db/oracle-provider.test.ts +843 -0
- package/tests/integration/db/postgres-provider.test.ts +1382 -0
- package/tests/integration/db/redis-provider.test.ts +526 -0
- package/tests/integration/db/sqlite-provider.test.ts +480 -0
- package/tests/integration/seed/seed-pipeline.test.ts +102 -0
- package/tests/isolated/factory-singleton.test.ts +150 -0
- package/tests/isolated/use-storage-sync.test.ts +389 -0
- package/tests/run-components.sh +196 -0
- package/tests/setup-dom.ts +58 -0
- package/tests/setup.ts +40 -0
- package/tests/unit/api-errors.test.ts +210 -0
- package/tests/unit/code-generator-functions.test.ts +271 -0
- package/tests/unit/components/column-list.test.tsx +190 -0
- package/tests/unit/components/data-import-modal.test.tsx +441 -0
- package/tests/unit/components/studio-mobile-header.test.tsx +327 -0
- package/tests/unit/data-charts-functions.test.ts +496 -0
- package/tests/unit/data-import-functions.test.ts +320 -0
- package/tests/unit/data-import-utils.test.ts +125 -0
- package/tests/unit/db/base-provider.test.ts +517 -0
- package/tests/unit/db/errors.test.ts +403 -0
- package/tests/unit/db/factory.test.ts +436 -0
- package/tests/unit/db/pool-manager.test.ts +440 -0
- package/tests/unit/db/query-limiter.test.ts +387 -0
- package/tests/unit/db/sql-base.test.ts +438 -0
- package/tests/unit/lib/api/error-codes.test.ts +39 -0
- package/tests/unit/lib/audit.test.ts +326 -0
- package/tests/unit/lib/auth.test.ts +146 -0
- package/tests/unit/lib/connection-string-parser.test.ts +424 -0
- package/tests/unit/lib/data-masking.test.ts +583 -0
- package/tests/unit/lib/db-icons.test.tsx +41 -0
- package/tests/unit/lib/monitoring-thresholds.test.ts +133 -0
- package/tests/unit/lib/oidc.test.ts +509 -0
- package/tests/unit/lib/query-generators.test.ts +127 -0
- package/tests/unit/lib/storage/factory.test.ts +71 -0
- package/tests/unit/lib/storage/local-storage.test.ts +114 -0
- package/tests/unit/lib/storage/providers/postgres.test.ts +312 -0
- package/tests/unit/lib/storage/providers/sqlite.test.ts +232 -0
- package/tests/unit/lib/storage/storage-facade-extended.test.ts +331 -0
- package/tests/unit/lib/storage/storage-facade.test.ts +184 -0
- package/tests/unit/lib/storage.test.ts +317 -0
- package/tests/unit/lib/time-series-buffer.test.ts +212 -0
- package/tests/unit/lib/utils.test.ts +24 -0
- package/tests/unit/llm/base-provider.test.ts +238 -0
- package/tests/unit/llm/config.test.ts +262 -0
- package/tests/unit/llm/custom-provider.test.ts +281 -0
- package/tests/unit/llm/gemini-provider.test.ts +248 -0
- package/tests/unit/llm/llm-factory.test.ts +155 -0
- package/tests/unit/llm/ollama-provider.test.ts +288 -0
- package/tests/unit/llm/openai-provider.test.ts +324 -0
- package/tests/unit/llm/retry.test.ts +180 -0
- package/tests/unit/llm/streaming.test.ts +355 -0
- package/tests/unit/logger.test.ts +198 -0
- package/tests/unit/mongodb-completions.test.ts +516 -0
- package/tests/unit/pivot-table-functions.test.ts +76 -0
- package/tests/unit/query-cancelled-error.test.ts +81 -0
- package/tests/unit/schema-diff/diff-engine.test.ts +367 -0
- package/tests/unit/schema-diff/migration-generator.test.ts +513 -0
- package/tests/unit/seed/config-loader.test.ts +73 -0
- package/tests/unit/seed/connection-filter.test.ts +91 -0
- package/tests/unit/seed/credential-resolver.test.ts +85 -0
- package/tests/unit/seed/index.test.ts +72 -0
- package/tests/unit/seed/resolve-connection.test.ts +74 -0
- package/tests/unit/seed/types.test.ts +129 -0
- package/tests/unit/sql/alias-extractor.test.ts +444 -0
- package/tests/unit/sql/statement-splitter.test.ts +348 -0
- package/tests/unit/sql-completions.test.ts +463 -0
- package/tests/unit/ssh-tunnel.test.ts +465 -0
- package/tsconfig.json +42 -0
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
# Data Masking
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Automatically mask sensitive data (PII, credentials, financial info) in query results based on user role and column patterns. Protect sensitive information while maintaining data utility.
|
|
5
|
+
|
|
6
|
+
## Problem Statement
|
|
7
|
+
Organizations face challenges with sensitive data visibility:
|
|
8
|
+
- Developers seeing production PII during debugging
|
|
9
|
+
- Screenshots/screen shares exposing customer data
|
|
10
|
+
- Compliance requirements (GDPR, HIPAA, PCI-DSS)
|
|
11
|
+
- Accidental data exposure in presentations
|
|
12
|
+
|
|
13
|
+
Current solutions are inadequate:
|
|
14
|
+
- Database-level masking (complex to configure)
|
|
15
|
+
- Manual data sanitization (time-consuming)
|
|
16
|
+
- Separate dev/prod environments (data drift)
|
|
17
|
+
- Trust-based access (risky)
|
|
18
|
+
|
|
19
|
+
## Proposed Solution
|
|
20
|
+
Client-side data masking with:
|
|
21
|
+
- Automatic detection of sensitive columns
|
|
22
|
+
- Role-based masking rules (admin sees all, user sees masked)
|
|
23
|
+
- Toggle to reveal/hide masked data
|
|
24
|
+
- Configurable masking patterns
|
|
25
|
+
|
|
26
|
+
## Features
|
|
27
|
+
|
|
28
|
+
### 1. Automatic Column Detection
|
|
29
|
+
Detect sensitive data by column name patterns:
|
|
30
|
+
|
|
31
|
+
| Pattern | Type | Example |
|
|
32
|
+
|---------|------|---------|
|
|
33
|
+
| `*email*`, `*mail*` | Email | `j***@example.com` |
|
|
34
|
+
| `*phone*`, `*mobile*`, `*tel*` | Phone | `+90 5** *** ** 45` |
|
|
35
|
+
| `*password*`, `*secret*`, `*token*` | Credential | `••••••••` |
|
|
36
|
+
| `*ssn*`, `*social*`, `tc_*` | ID Number | `***-**-1234` |
|
|
37
|
+
| `*card*`, `*credit*` | Credit Card | `**** **** **** 4242` |
|
|
38
|
+
| `*salary*`, `*income*`, `*balance*` | Financial | `$***,***` |
|
|
39
|
+
| `*address*`, `*street*` | Address | `*** Main St, ***` |
|
|
40
|
+
| `*birth*`, `*dob*` | Birth Date | `**/**/1990` |
|
|
41
|
+
| `*ip*`, `ip_address` | IP Address | `192.***.***.1` |
|
|
42
|
+
|
|
43
|
+
### 2. Masking Toggle UI
|
|
44
|
+
```
|
|
45
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
46
|
+
│ Results 🔒 Masking: ON [Toggle] │
|
|
47
|
+
├─────────────────────────────────────────────────────────────┤
|
|
48
|
+
│ id │ name │ email │ phone │ │
|
|
49
|
+
├────┼─────────────┼────────────────────┼────────────────┤ │
|
|
50
|
+
│ 1 │ John Doe │ j***@example.com │ +90 5** *** 45│ │
|
|
51
|
+
│ 2 │ Jane Smith │ j***@company.org │ +1 55* *** 89 │ │
|
|
52
|
+
│ 3 │ Bob Wilson │ b***@test.io │ +44 7** *** 12│ │
|
|
53
|
+
└─────────────────────────────────────────────────────────────┘
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
When toggled OFF (admin only):
|
|
57
|
+
```
|
|
58
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
59
|
+
│ Results 🔓 Masking: OFF [Toggle] │
|
|
60
|
+
├─────────────────────────────────────────────────────────────┤
|
|
61
|
+
│ id │ name │ email │ phone │ │
|
|
62
|
+
├────┼─────────────┼────────────────────┼─────────────────┤ │
|
|
63
|
+
│ 1 │ John Doe │ john@example.com │ +90 532 123 4545│ │
|
|
64
|
+
│ 2 │ Jane Smith │ jane@company.org │ +1 555 987 6589 │ │
|
|
65
|
+
│ 3 │ Bob Wilson │ bob@test.io │ +44 789 012 3412│ │
|
|
66
|
+
└─────────────────────────────────────────────────────────────┘
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 3. Role-Based Access
|
|
70
|
+
```
|
|
71
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
72
|
+
│ User Role Settings │
|
|
73
|
+
├─────────────────────────────────────────────────────────────┤
|
|
74
|
+
│ Admin: │
|
|
75
|
+
│ • Can toggle masking on/off │
|
|
76
|
+
│ • Sees "Reveal" button on masked cells │
|
|
77
|
+
│ • Access to masking configuration │
|
|
78
|
+
│ │
|
|
79
|
+
│ User: │
|
|
80
|
+
│ • Masking always enabled │
|
|
81
|
+
│ • Cannot reveal individual values │
|
|
82
|
+
│ • No access to masking settings │
|
|
83
|
+
└─────────────────────────────────────────────────────────────┘
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 4. Column-Level Masking Indicator
|
|
87
|
+
```
|
|
88
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
89
|
+
│ email 🔒 │ phone 🔒 │ name │
|
|
90
|
+
├───────────────────────┼──────────────────────┼──────────────┤
|
|
91
|
+
│ j***@example.com │ +90 5** *** ** 45 │ John Doe │
|
|
92
|
+
└───────────────────────┴──────────────────────┴──────────────┘
|
|
93
|
+
```
|
|
94
|
+
- Lock icon indicates masked column
|
|
95
|
+
- Hover shows: "This column is masked (email)"
|
|
96
|
+
- Click lock for masking details
|
|
97
|
+
|
|
98
|
+
### 5. Masking Patterns
|
|
99
|
+
|
|
100
|
+
#### Email Masking
|
|
101
|
+
```
|
|
102
|
+
john.doe@example.com → j***.***@example.com
|
|
103
|
+
a@b.com → a@***.com (preserve if too short)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### Phone Masking
|
|
107
|
+
```
|
|
108
|
+
+90 532 123 4545 → +90 5** *** ** 45
|
|
109
|
+
(555) 123-4567 → (555) ***-**67
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### Credit Card Masking
|
|
113
|
+
```
|
|
114
|
+
4111 1111 1111 1111 → **** **** **** 1111
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
#### Custom Patterns
|
|
118
|
+
```
|
|
119
|
+
Full mask: ••••••••
|
|
120
|
+
Partial mask: abc***xyz (preserve start/end)
|
|
121
|
+
Hash mask: #a3f2b1 (consistent hash)
|
|
122
|
+
Null mask: [REDACTED]
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### 6. Quick Reveal (Admin Only)
|
|
126
|
+
```
|
|
127
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
128
|
+
│ j***@example.com [👁️] │
|
|
129
|
+
└─────────────────────────────────────────────────────────────┘
|
|
130
|
+
↓ Click reveal
|
|
131
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
132
|
+
│ john.doe@example.com [🔒] │
|
|
133
|
+
└─────────────────────────────────────────────────────────────┘
|
|
134
|
+
```
|
|
135
|
+
- Per-cell reveal button for admins
|
|
136
|
+
- Auto-hide after 10 seconds
|
|
137
|
+
- Audit log for reveals
|
|
138
|
+
|
|
139
|
+
## Technical Considerations
|
|
140
|
+
|
|
141
|
+
### Masking Configuration
|
|
142
|
+
```typescript
|
|
143
|
+
interface MaskingConfig {
|
|
144
|
+
enabled: boolean;
|
|
145
|
+
patterns: MaskingPattern[];
|
|
146
|
+
roleOverrides: {
|
|
147
|
+
admin: { canToggle: boolean; canReveal: boolean };
|
|
148
|
+
user: { canToggle: boolean; canReveal: boolean };
|
|
149
|
+
};
|
|
150
|
+
auditLog: boolean;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
interface MaskingPattern {
|
|
154
|
+
id: string;
|
|
155
|
+
name: string;
|
|
156
|
+
columnPatterns: string[]; // Regex patterns for column names
|
|
157
|
+
valuePatterns?: string[]; // Regex patterns for values (optional)
|
|
158
|
+
maskType: 'email' | 'phone' | 'card' | 'full' | 'partial' | 'custom';
|
|
159
|
+
maskFunction?: (value: string) => string; // Custom masking
|
|
160
|
+
preserveLength?: boolean;
|
|
161
|
+
preserveFormat?: boolean;
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Default Patterns (Static)
|
|
166
|
+
```typescript
|
|
167
|
+
const DEFAULT_PATTERNS: MaskingPattern[] = [
|
|
168
|
+
{
|
|
169
|
+
id: 'email',
|
|
170
|
+
name: 'Email Addresses',
|
|
171
|
+
columnPatterns: [/email/i, /e_mail/i, /mail_address/i],
|
|
172
|
+
maskType: 'email',
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
id: 'phone',
|
|
176
|
+
name: 'Phone Numbers',
|
|
177
|
+
columnPatterns: [/phone/i, /mobile/i, /tel/i, /gsm/i],
|
|
178
|
+
maskType: 'phone',
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
id: 'password',
|
|
182
|
+
name: 'Passwords & Secrets',
|
|
183
|
+
columnPatterns: [/password/i, /secret/i, /token/i, /api_key/i],
|
|
184
|
+
maskType: 'full',
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
id: 'credit_card',
|
|
188
|
+
name: 'Credit Cards',
|
|
189
|
+
columnPatterns: [/card/i, /credit/i, /cc_/i],
|
|
190
|
+
maskType: 'card',
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
id: 'ssn',
|
|
194
|
+
name: 'ID Numbers',
|
|
195
|
+
columnPatterns: [/ssn/i, /social/i, /tc_no/i, /identity/i],
|
|
196
|
+
maskType: 'partial',
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
id: 'financial',
|
|
200
|
+
name: 'Financial Data',
|
|
201
|
+
columnPatterns: [/salary/i, /income/i, /balance/i, /amount/i],
|
|
202
|
+
maskType: 'full',
|
|
203
|
+
},
|
|
204
|
+
];
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Masking Functions
|
|
208
|
+
```typescript
|
|
209
|
+
function maskEmail(value: string): string {
|
|
210
|
+
const [local, domain] = value.split('@');
|
|
211
|
+
if (!domain) return '***@***.***';
|
|
212
|
+
const maskedLocal = local[0] + '***';
|
|
213
|
+
return `${maskedLocal}@${domain}`;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function maskPhone(value: string): string {
|
|
217
|
+
// Keep country code and last 2 digits
|
|
218
|
+
return value.replace(/\d(?=\d{2})/g, '*');
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function maskCreditCard(value: string): string {
|
|
222
|
+
// Keep last 4 digits
|
|
223
|
+
const digits = value.replace(/\D/g, '');
|
|
224
|
+
const last4 = digits.slice(-4);
|
|
225
|
+
return `**** **** **** ${last4}`;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function maskPartial(value: string, showStart = 1, showEnd = 2): string {
|
|
229
|
+
if (value.length <= showStart + showEnd) return '***';
|
|
230
|
+
const start = value.slice(0, showStart);
|
|
231
|
+
const end = value.slice(-showEnd);
|
|
232
|
+
const middle = '*'.repeat(Math.min(value.length - showStart - showEnd, 5));
|
|
233
|
+
return `${start}${middle}${end}`;
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Integration with Results Grid
|
|
238
|
+
```typescript
|
|
239
|
+
// In ResultsGrid.tsx
|
|
240
|
+
function formatCellValue(
|
|
241
|
+
value: any,
|
|
242
|
+
columnName: string,
|
|
243
|
+
maskingConfig: MaskingConfig,
|
|
244
|
+
userRole: 'admin' | 'user'
|
|
245
|
+
): { display: string; isMasked: boolean; originalValue?: any } {
|
|
246
|
+
if (!maskingConfig.enabled) {
|
|
247
|
+
return { display: String(value), isMasked: false };
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const pattern = findMatchingPattern(columnName, maskingConfig.patterns);
|
|
251
|
+
if (!pattern) {
|
|
252
|
+
return { display: String(value), isMasked: false };
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const masked = applyMask(value, pattern);
|
|
256
|
+
return {
|
|
257
|
+
display: masked,
|
|
258
|
+
isMasked: true,
|
|
259
|
+
originalValue: userRole === 'admin' ? value : undefined,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Storage
|
|
265
|
+
```typescript
|
|
266
|
+
// Masking config stored in localStorage
|
|
267
|
+
const MASKING_CONFIG_KEY = 'libredb_masking_config';
|
|
268
|
+
|
|
269
|
+
// User preference for masking toggle
|
|
270
|
+
const MASKING_ENABLED_KEY = 'libredb_masking_enabled';
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## UI Components
|
|
274
|
+
|
|
275
|
+
### New Components
|
|
276
|
+
- `MaskingToggle.tsx` - Global masking on/off switch
|
|
277
|
+
- `MaskedCell.tsx` - Cell with masking and reveal button
|
|
278
|
+
- `MaskingIndicator.tsx` - Column header lock icon
|
|
279
|
+
- `MaskingSettings.tsx` - Configuration panel (admin only)
|
|
280
|
+
- `RevealButton.tsx` - Eye icon to reveal single value
|
|
281
|
+
|
|
282
|
+
### Integration Points
|
|
283
|
+
- Results toolbar: Masking toggle
|
|
284
|
+
- Column headers: Lock icon for masked columns
|
|
285
|
+
- Cell render: MaskedCell component
|
|
286
|
+
- Settings menu: Masking configuration
|
|
287
|
+
|
|
288
|
+
## User Flow
|
|
289
|
+
|
|
290
|
+
### User (Non-Admin)
|
|
291
|
+
```
|
|
292
|
+
1. User runs query
|
|
293
|
+
↓
|
|
294
|
+
2. Results display with masked columns (automatic)
|
|
295
|
+
↓
|
|
296
|
+
3. Lock icons visible on masked columns
|
|
297
|
+
↓
|
|
298
|
+
4. Cannot reveal or toggle masking
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Admin
|
|
302
|
+
```
|
|
303
|
+
1. Admin runs query
|
|
304
|
+
↓
|
|
305
|
+
2. Results display with masked columns (default)
|
|
306
|
+
↓
|
|
307
|
+
3. Toggle available: [🔒 Masking: ON]
|
|
308
|
+
↓
|
|
309
|
+
4. Click toggle → All data revealed
|
|
310
|
+
↓
|
|
311
|
+
5. Or click individual cell → Reveal single value
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## Configuration UI (Admin)
|
|
315
|
+
```
|
|
316
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
317
|
+
│ Data Masking Settings │
|
|
318
|
+
├─────────────────────────────────────────────────────────────┤
|
|
319
|
+
│ [ ] Enable data masking globally │
|
|
320
|
+
│ │
|
|
321
|
+
│ Masking Patterns: │
|
|
322
|
+
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
323
|
+
│ │ [✓] Email (email, mail, e_mail) │ │
|
|
324
|
+
│ │ [✓] Phone (phone, mobile, tel, gsm) │ │
|
|
325
|
+
│ │ [✓] Passwords (password, secret, token, api_key) │ │
|
|
326
|
+
│ │ [✓] Credit Cards (card, credit, cc_) │ │
|
|
327
|
+
│ │ [✓] ID Numbers (ssn, tc_no, identity) │ │
|
|
328
|
+
│ │ [ ] Financial (salary, income, balance) │ │
|
|
329
|
+
│ └─────────────────────────────────────────────────────────┘ │
|
|
330
|
+
│ │
|
|
331
|
+
│ Role Permissions: │
|
|
332
|
+
│ • Admin: Can toggle and reveal │
|
|
333
|
+
│ • User: Always masked, no reveal │
|
|
334
|
+
│ │
|
|
335
|
+
│ [Reset Defaults] [Save] │
|
|
336
|
+
└─────────────────────────────────────────────────────────────┘
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## Visual Design
|
|
340
|
+
|
|
341
|
+
### Masked Value Styling
|
|
342
|
+
```css
|
|
343
|
+
.masked-value {
|
|
344
|
+
color: #888;
|
|
345
|
+
font-family: monospace;
|
|
346
|
+
letter-spacing: 1px;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.masked-column-header {
|
|
350
|
+
display: flex;
|
|
351
|
+
align-items: center;
|
|
352
|
+
gap: 4px;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
.masking-lock-icon {
|
|
356
|
+
color: #f59e0b; /* Amber */
|
|
357
|
+
width: 12px;
|
|
358
|
+
height: 12px;
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Toggle Badge
|
|
363
|
+
```
|
|
364
|
+
🔒 Masking: ON (amber background)
|
|
365
|
+
🔓 Masking: OFF (red background, warning)
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
## Acceptance Criteria
|
|
369
|
+
- [ ] Sensitive columns are automatically detected by name
|
|
370
|
+
- [ ] Masked values display with partial visibility
|
|
371
|
+
- [ ] Lock icon appears on masked column headers
|
|
372
|
+
- [ ] Admin can toggle masking on/off globally
|
|
373
|
+
- [ ] Admin can reveal individual cell values
|
|
374
|
+
- [ ] User cannot toggle or reveal masked data
|
|
375
|
+
- [ ] Masking persists across sessions
|
|
376
|
+
- [ ] Export respects masking (user exports masked data)
|
|
377
|
+
- [ ] Works with all supported databases
|
|
378
|
+
|
|
379
|
+
## Security Considerations
|
|
380
|
+
- Masking is client-side only (for display)
|
|
381
|
+
- Server still returns full data to authorized users
|
|
382
|
+
- For true security, use database-level masking
|
|
383
|
+
- Audit log for reveal actions (optional)
|
|
384
|
+
- Clear warning when masking is disabled
|
|
385
|
+
|
|
386
|
+
## Edge Cases
|
|
387
|
+
- Very short values (e.g., 3-char email)
|
|
388
|
+
- NULL values (show as NULL, not masked)
|
|
389
|
+
- Non-string columns (numbers, booleans)
|
|
390
|
+
- Binary/blob data
|
|
391
|
+
- Very long values (truncate then mask)
|
|
392
|
+
|
|
393
|
+
## Estimated Effort
|
|
394
|
+
Low-Medium complexity
|
|
395
|
+
|
|
396
|
+
## Priority
|
|
397
|
+
P2 - Compliance & Security
|
|
398
|
+
|
|
399
|
+
## Phase 1 (Initial - Static)
|
|
400
|
+
- Hardcoded masking patterns
|
|
401
|
+
- Toggle on/off for admins
|
|
402
|
+
- Basic email, phone, password masking
|
|
403
|
+
- Column-based detection only
|
|
404
|
+
|
|
405
|
+
## Phase 2 (Future)
|
|
406
|
+
- Custom pattern configuration
|
|
407
|
+
- Value-based detection (regex on content)
|
|
408
|
+
- Audit logging
|
|
409
|
+
- Export policy settings
|
|
410
|
+
- Per-connection masking rules
|
|
411
|
+
|
|
412
|
+
## Dependencies
|
|
413
|
+
- Role-based access (existing)
|
|
414
|
+
- ResultsGrid component (existing)
|
|
415
|
+
|
|
416
|
+
## Related Features
|
|
417
|
+
- Query Playground (can combine with masking)
|
|
418
|
+
- Data Export (respect masking settings)
|