Skip to content

test: enhance test coverage for field encryption [INS-4133] - #10763

Open
bobqiu-kong wants to merge 22 commits into
feat/encrypt-db-11-migration-testsfrom
test/ins-4133-encrypt-sensitive-data
Open

bobqiu-kong wants to merge 22 commits into
feat/encrypt-db-11-migration-testsfrom
test/ins-4133-encrypt-sensitive-data

Conversation

@bobqiu-kong

@bobqiu-kong bobqiu-kong commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Automated end-to-end coverage for local database field encryption (INS-2368), tracked by INS-4133. It implements the cases of the test plan that can be driven through packages/insomnia-test (19 of the plan's 20; case 18, Scratch Pad, is not covered yet) and adds the Page / Flow / fixture support they need.

This PR sits on top of the INS-2368 stack (#10749 – #10759) and only touches packages/insomnia-test. No app code changes.

Changes

Specs — tests/workspace/field-encryption/ (30 tests)

Test plan case Spec
01 Sensitive fields encrypted on disk, plaintext in the app on-disk-encryption
02 Requests still send the real credentials request-sends-real-credentials
03 Plaintext legacy database migrates on first launch legacy-db-migration
04 Client certificate passphrase encrypted, mTLS still works client-certificate-mtls
05 Other protected secrets (every model in the design doc's "Sensitive Fields Analysis") sensitive-fields, ui-created-secrets
06 Export / import stays plaintext export-stays-plaintext
07 Data survives restarts survives-restart
08, 09 Copy Key / Export Key key-export
10, 11 inso with the key (option, env var, both key formats; missing / wrong / malformed key) inso-encryption-key
12, 13 Dialog B: Reset affected fields / Continue without decryption decryption-failure-dialog
14, 15, 17 Dialog A: key unavailable, Reset local encryption key, disabled buttons key-unavailable-dialog
16 Datastore cannot be loaded (native startup error) database-load-failure
19 Interrupted migration (plaintext and ciphertext mixed) interrupted-migration
20 inso reads plaintext sources without a key inso-plaintext-sources

sensitive-fields seeds each model through the app's own database layer (docCreate) and checks, before and after two restarts, that sensitive paths are ciphertext on disk, no secret is left in any .db file, non-sensitive paths (client ids, key ids, cookie keys…) stay plaintext, and the app still reads the original values.

Framework (packages/insomnia-test)

  • Migrated, function-level, from test/refactor_e2e_tests: AppFlow.restart, PageManager.setWindow, ExportFlow.exportCollection, ImportFlow.importFile, CookieFlow, CertificatesFlow.addClientCertificate and their pages / models / enums.
  • Migrated from test/e2e-openai-3.2-support: runInso and InsoFlow.lintSpec.
  • New: FieldEncryptionFlow with the LocalEncryptionKeyComponent (Preferences > General) and FieldEncryptionIssueComponent (dialogs A and B); InsoFlow.runCollection; AppFlow.relaunch; raw .db readers (readRawDocs, readRawDbText) and createDoc / updateDoc; seeding helpers for a degraded key, undecryptable fields and the legacy database (misc/field-encryption-fixtures.ts).
  • userAtStartup fixture: like user, but touches no UI during setup, for apps that start behind a blocking dialog. The teardown of relaunched apps moved into a shared closeRelaunchedApp; user behaves as before.
  • Native startup dialog: misc/native-dialog-stub.cjs, preloaded into the main process with the new preloadScripts / extraEnv options of launchInsomniaElectron, answers dialog.showMessageBox and records shell.openPath.
  • Fix: pages that built dialog locators in field initializers (CookiePage, CertificatesPage, ExportPage, ImportPage) kept pointing at the closed window after AppFlow.restart(). They now use getters.

Notes for reviewers

  • inso specs run the built bundle: run npm run build -w insomnia-inso first. They work on copies of the data directory, because inso rewrites the files it loads.
  • Case 16 preloads the stub with Electron's --require, which a packaged app ignores, so that spec only works in dev mode (the default).
  • Case 04 turns SSL validation off to trust the mock server's CA (there is no CA certificate Flow yet).
  • Case 20's "Git Sync repository" is a directory generated in Git Sync's .insomnia/<Type>/*.yml layout, not a real sync.
  • Not covered: case 18 (Scratch Pad has no Flow), and OAuth 2 / Git / cloud credentials are created through the database layer, not their UIs.

Testing

npm run build -w insomnia-inso
cd packages/insomnia-test
npx playwright test tests/workspace/field-encryption   # 30 passed
npm run type-check && npx eslint .

🤖 Generated with Claude Code

@bobqiu-kong
bobqiu-kong added this pull request to stack #10760 November 12, 2026 05:56
@bobqiu-kong bobqiu-kong changed the title test: track test coverage for field encryption [INS-4133] test: enhance test coverage for field encryption [INS-4133] Nov 12, 2026
@bobqiu-kong
bobqiu-kong force-pushed the test/ins-4133-encrypt-sensitive-data branch from 9146734 to e2dc1c5 Compare November 12, 2026 07:51
@bobqiu-kong
bobqiu-kong marked this pull request as ready for review November 12, 2026 07:51
@github-actions

github-actions Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

❌ KSAI Review: Failed

The review did not complete (no-result). Nothing was salvaged to post as a review. What it spent is below; see the workflow run for details


Run report (federated) · 0 paid runs · cost not recoverable from a partial log
# Engine Result Model
1 opencode `` glm-5.3/high

yaoweiprc and others added 20 commits November 13, 2026 10:31
The design of the field-level encryption of the local NeDB files: the sensitive fields, the approaches that were compared, the serialization hooks, the key lifecycle, the user-facing error handling, the migration and the implementation plan. Documentation only.

Part 1 of 11 of the field encryption stack (INS-2368), which replaces #10666.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
AES-256-GCM value encryption with the enc:insomnia:v1: format, the walk over encrypted field paths, and the NeDB serialization hooks with their failure report. Pure functions with no Electron or model dependency; the path table is injected.

Part 2 of 11 of the field encryption stack (INS-2368), which replaces #10666.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
An encrypted() mark on the Zod schema fields, the derivation of the encrypted paths from the schemas, the marks on the models already on Zod, and temporary encryptedFields arrays for the five models that are still plain interfaces. A snapshot test makes every change of the encrypted set visible in review.

Part 3 of 11 of the field encryption stack (INS-2368), which replaces #10666.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…INS-2368]

createNedbDatabase().init() takes a fieldEncryptionKey and attaches the hooks to the datastores that have encrypted fields. init() now waits for every datastore to load and rejects with the names of the ones that failed instead of hanging, and the failure report is reconciled after the load.

Part 4 of 11 of the field encryption stack (INS-2368), which replaces #10666.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
INS-2368]

setItemDurable (temp file, fsync, rename), getItemStrict (null only when the file does not exist) and isSameFile. The key file must never be lost or mistaken for missing, which the existing buffered setItem / defaulting getItem cannot promise. Existing methods and callers are unchanged.

Part 5 of 11 of the field encryption stack (INS-2368), which replaces #10666.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…S-2368]

The local key is generated on the first launch, protected with the asynchronous safeStorage API, written durably and verified before any datastore is encrypted, and loaded into mainDatabase.init(). When it cannot be used the database opens without encryption (degraded mode) and the key file is never replaced. The renderer cannot reach the key file through the storage IPC handlers.

Part 6 of 11 of the field encryption stack (INS-2368), which replaces #10666.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ad failures [INS-2368]

The main process side of the user-facing errors: the failure report can be refreshed and reset, a controller and a FieldEncryptionIpcHandler expose getStatus / resetFailedFields / resetKey / dismiss to the renderer, the key reset sets the key file aside after a native confirmation and relaunches, and a datastore that fails to load shows a native error box instead of a hang.

Part 7 of 11 of the field encryption stack (INS-2368), which replaces #10666.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…NS-2368]

FieldEncryptionIssueModal, mounted with the other modals, asks the main process for the status once and offers the choices of the two situations: some fields cannot be decrypted, or the local key is not available. The renderer reaches the handler through the fieldEncryption trigger in ui/ipc.ts.

Part 8 of 11 of the field encryption stack (INS-2368), which replaces #10666.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…nces [INS-2368]

A Local Encryption Key section in Preferences > General with Copy Key (base64 of the JWK) and Export Key (JWK JSON file), each behind a confirmation. Two more fieldEncryption handler methods, isKeyAvailable and getKey, and one helper in insomnia-data that builds both forms.

Part 9 of 11 of the field encryption stack (INS-2368), which replaces #10666.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…MNIA_ENCRYPTION_KEY [INS-2368]

inso accepts the key in both forms the app hands out and decrypts the NeDB datastores through the shared hooks. Without a key it warns how many encrypted values it found, a wrong key is an error that names the fields and never the values, and the key is hidden in --printOptions and not read from .insorc.

Part 10 of 11 of the field encryption stack (INS-2368), which replaces #10666.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…S-2368]

Tests only. The first launch with the key is the migration: on the plaintext insomnia-legacy-db fixture all sensitive fields are encrypted, the data is intact, and an interruption at any point is safe. One test on real NeDB files, one on the real mainDatabase.init(), and one Playwright smoke test on the real app.

Part 11 of 11 of the field encryption stack (INS-2368), which replaces #10666.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…S-2368]

Tests only. The first launch with the key is the migration: on the plaintext insomnia-legacy-db fixture all sensitive fields are encrypted, the data is intact, and an interruption at any point is safe. One test on real NeDB files, one on the real mainDatabase.init(), and one Playwright smoke test on the real app.

Part 11 of 11 of the field encryption stack (INS-2368), which replaces #10666.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- Implemented `inso-cli.ts` to run the locally built `inso` CLI, enabling command execution through Electron.
- Created `client-certificate.ts` model to define the structure for client certificates including cert, key, and optional passphrase.
- Developed `certificates.page.ts` to manage the UI interactions for adding and managing client certificates.
- Added `export.page.ts` for handling export functionalities and selecting export formats.
- Introduced tests for field encryption scenarios, ensuring sensitive data remains encrypted while being accessible in the app.
- Implemented various test cases for Bearer token handling, legacy database migration, and ensuring encrypted data survives application restarts.
- Added UI tests for verifying that client certificates added through the UI are stored securely and correctly.
- Added ImportFlow class to handle file imports from the project context menu.
- Created import.page.ts to manage the import dialog interactions.

feat: add field encryption utilities and fixtures

- Introduced field-encryption-fixtures.ts for handling legacy database and encryption key operations.
- Implemented functions for copying legacy databases, appending raw documents, and managing encryption keys.

feat: create cookie model and page interactions

- Defined Cookie type in cookie.ts to represent cookie attributes.
- Developed CookiePage class in cookie.page.ts for managing cookie operations, including adding, editing, and deleting cookies.

test: add tests for field encryption scenarios

- Created decryption-failure-dialog.spec.ts to test handling of decryption failures and affected fields.
- Implemented key-export.spec.ts to verify key export functionality and clipboard operations.
- Added key-unavailable-dialog.spec.ts to test behavior when the encryption key is unavailable, including resetting the key and handling degraded mode.
- Updated `runInso` function to accept custom environment variables, improving flexibility in test environments.
- Enhanced `launchInsomniaElectron` to support preload scripts and additional environment variables for better test isolation.
- Introduced a native dialog stub to simulate user interactions with dialogs during tests, allowing for more controlled testing scenarios.
- Added comprehensive tests for client certificate mTLS functionality, ensuring encrypted passphrases are handled correctly.
- Implemented tests for database load failures, ensuring the application handles corrupted databases gracefully without data loss.
- Created tests for decryption failure dialogs, verifying that the application prompts users appropriately when decryption issues occur.
- Developed tests for key export functionality, ensuring keys are handled securely and correctly.
- Added tests for interrupted migrations, ensuring that mixed encrypted and plaintext values are processed correctly.
- Enhanced existing tests to ensure sensitive fields remain encrypted on disk while being displayed as plaintext in the app.
- Removed outdated comments and consolidated test cases for clarity and maintainability.
@bobqiu-kong
bobqiu-kong force-pushed the test/ins-4133-encrypt-sensitive-data branch from feefeb7 to 9d748e3 Compare November 13, 2026 02:31
- Improved the `authFieldEditor` method to handle legacy test IDs during upgrades.
- Added an error dialog getter in `LocalEncryptionKeyComponent` for export failures.
- Updated `PreferencesComponent` to locate sidebar focus settings by input name.
- Introduced `EnabledLabelToggleComponent` for managing toggle button states.
- Implemented CA certificate management methods in `CertificatesFlow`.
- Added methods for handling CA and client certificate states in `CertificatesPage`.
- Enhanced `Tree` class to support legacy row handling during upgrades.
- Refactored field encryption tests to utilize new flow methods for error dialog assertions.
- Removed obsolete legacy database migration tests and added new upgrade tests for previous releases.

This branch has not been deployed

No deployments
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.

3 participants