Commit Graph
73 Commits
Author SHA1 Message Date
Bingbing 02f181483f feat(examples): create request from an example 2026-10-29 16:39:39 +08:00
Bingbing e53f9baadb feat(examples): save response as example 2026-10-29 16:39:38 +08:00
Bingbing b266c3c6f1 feat(examples): add example model and authoring
## Background

A request can only keep its latest response, so a request/response pair worth keeping has nowhere to live. This adds an Example document: a full snapshot of a request and a response, stored next to the request, listed in the sidebar and edited in its own tab.

## Changes

- Add the `Example` model (`exp_` prefix) with zod schemas for the request snapshot, the response snapshot, the client patch and the sidebar summary. Register it with the database, type maps, tree metadata and sync flags, so examples can be duplicated and synchronized.
- Add `services.example` (list, get, list by parents, create, update, remove, duplicate, create from request) and expose examples from the workspace data service.
- Extend the workspace children cache with example summaries and add a per-example query that carries the bodies, so workspace-wide reads stay small. The database change listener refreshes or drops an open example.
- Export and import examples in v5 files, including the generated 5.1 schema, and include them in Git sync.
- Add the example route and editor: request pane reusing the HTTP editors, response pane, breadcrumb entry under the parent request and redirect for stale URLs.
- Add example rows to the sidebar with collapse, drag and drop and rename, and give the tab a code icon instead of a method badge.
- Cover the model, services, cache and file format with unit tests and add a smoke test.

Refs INS-3997
2026-10-29 16:39:38 +08:00
Bingbing 7863413757 fix: clear stale sync flags after a project leaves cloud sync [INS-3899] (#10668)
## Background

Workspace `hasUncommittedChanges` / `hasUnpushedChanges` flags are written only by cloud sync. When a project stopped being a cloud project, those flags were never cleared, so the project overview cards kept showing "Uncommitted changes".

Repro:

1. Open a cloud project whose workspaces have uncommitted changes.
2. Remove the project from the remote.
3. Open the project overview. The cards still show "Uncommitted changes" although the project is now local.

A project converted from cloud to git carries the same residual flags, because the values come from its former cloud state.

## Changes

- Clear both workspace sync flags when a project's `remoteId` becomes `null` in the project service. Remote deletion, conversion to local, cross-organization move, and conversion to git all update the project through this service.
- Reuse the cleanup in the startup database repair to fix existing stale records. Only dirty workspace metas are written, and `modified` is preserved.
- Add service and repair tests.

## Testing

- `npm test -w insomnia-data` (538 tests)
- `npm run type-check -w insomnia-data`
- `npm run lint -w insomnia-data`

## References

- INS-3899
2026-10-28 09:58:34 +00:00
George 7498c30b57 fix(sidebar): scope the del shortcut without backspace (#10644)
* fix: scope the del shortcut without backspace

* test: add e2e
2026-10-22 07:49:51 +00:00
yaoweiprcandClaude Sonnet 5.5 db419cdb87 feat: Debug Mode setting that enables the Git commit diagnostic panel [INS-3829] (#10470)
* diagnostic panel

* ci: temporarily enable code signing for PR #10470 recurring builds

* Revert "ci: temporarily enable code signing for PR #10470 recurring builds"

This reverts commit d10322c979.

* feat: gate the Git change analysis behind a Debug Mode setting [INS-3829]

Add a per-user `debugMode` setting, toggled from Help > Enable/Disable Debug
Mode (right under Show App Logs Folder). The Git commit dialog's change
analysis is now only computed and rendered while it is on.

- diffFileLoader skips buildInsomniaChangeReport and returns no diagnostics
  when debugMode is off, so the dialog pays nothing for it.
- The menu label follows the setting across every open window via db.onChange.

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

* fix: key change-report containers by parent id instead of display path

The container identity embedded the parent's display path, so renaming a
folder or collection made every descendant look moved and skipped reorder
detection inside the renamed parent, and same-named parents were merged into
one reorder group. Key containers by the parent id and keep the path only as
a display label.

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

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-21 13:53:50 +00:00
Curry Yang 4c35c25626 feat/option toggle prompt (#10607)
* change option text

* add space between icon

* add option toggle prompt

* fix smoke test

* fix comment

* update response clear UI
2026-10-21 18:32:18 +08:00
George 59931459f5 feat: support del shortcut in the sidebar (#10633) 2026-10-21 17:11:08 +08:00
Bingbing 0ebcd43654 refactor: decouple scripting environment imports (#10482)
[INS-3767](https://konghq.atlassian.net/browse/INS-3767)

## Summary
- Remove scripting-environment imports from Insomnia application modules.
- Move shared faker, URL helpers, and response reason data into appropriate insomnia-data modules.
- Move certificate matching behavior and its test into the ClientCertificate model.
- Update all callers and remove obsolete module paths.

## Verification
- insomnia-data type-check and lint
- insomnia-scripting-environment lint and tests
- insomnia type-check
- URL/certificate tests: 50 passed
- circular-reference check: no new circular dependencies; insomnia-scripting-environment has 0 cycles

The existing scripting-environment tsconfig is intentionally unchanged here; its source-wide type-check scope is enabled in the stacked sendRequest PR after the remaining Insomnia runtime dependency is removed.
2026-10-21 14:29:55 +08:00
Kent Wang 07a0b24adf feat: Add F2 shortcut to rename entity name on sidebar (#10614)
* support rename by f2 shortcut on sidebar

* fix issues from comment

* refine the modal
2026-10-20 09:53:21 +00:00
Bingbing bf61f6ba45 fix: stop restamping ApiSpec.modified on startup and git round-trips (#10625)
## Background

In a Git-synced project, restarting Insomnia without any change marked every design document as modified in the Git staging list. The diff of each affected YAML contained exactly one line: the embedded ApiSpec `meta.modified` timestamp.

The v5 design-doc YAML does not serialize `ApiSpec.fileName` (the v5 schema has no such field), while v5 import parses a missing `fileName` as an empty string. Any git round-trip therefore reset `fileName` to empty in the database, and the startup repair (`_applyApiSpecName`) rewrote it via `docUpdate`, which unconditionally restamped `modified: Date.now()` for every design document in one burst. RepoFileWatcher then re-exported the database to disk and git status reported all files as modified, repeating on every startup until committed.

## Changes

- Import: fall back `ApiSpec.fileName` to the file top-level name when the spec uses the `{ contents }` shape, so a round-trip never stores an empty fileName.
- Repair: skip the fileName backfill when it would write the existing value; a no-op write only restamps `modified`.
- Regression tests for both behaviors.

Fixes INS-4058
2026-10-20 02:58:17 +00:00
Kent Wang 25c20ce0c3 feat: Add incompatible fields check for cloud sync document (#10605)
* add basic utility for cloud sync check
* do not show error when entire deleted
* add confirmation window when submit contains unknown fields in cloud sync
2026-10-19 18:21:13 +08:00
Bingbing 499d95faba fix: resolve vault secrets in variable source and address review feedback [INS-3943] (#10608)
## Background

Hovering a `{{ _.vault.key }}` chip showed no source: vault secrets are stored under the reserved `__insomnia_vault` key in each environment and only surface under the runtime `vault` namespace after decryption, while the key source map was built by a parallel walk over the raw environment data in `getRenderContext`, duplicating the merge semantics that `buildRenderContext` implements for values.

## Changes

- Move key source registration into `buildRenderContext`, where the values are merged. Registration runs in the same order the runtime resolves values: the `__insomnia_vault` entries of every environment are recorded under the `vault` namespace first, then every environment's plain data walk — so a legacy plaintext `vault` key, which import and sync can carry without reserved-key validation, wins over sealed values just like it does in the final vault spread.
- Unify source labels to `<environment type> : <name>` — Project Environment, Collection Environment and Folder Environment; runner upload data and script variables keep their own type names.
- Prefix the source line in the hover tooltip with `Source`, matching the live preview modal.
- Rename the setting to "Template tags show variable source and value" so its scope is obvious from the name.
2026-10-15 08:53:43 +00:00
Kent Wang eb0b49f7a3 feat: Migrate collection and document workspace zod schema and type definitions- #10520 (#10582)
* migrate request related p2
- grpc-request
- cookie-jar
- fix ts errors

* add unit test to check field mismatch
* migrate request group model
* migrate the socket io request and import parser
* migrate websocket schema and fix ts error
* fix order issue and add unit tests
2026-10-15 13:45:30 +08:00
yaoweiprcandClaude Opus 5.5 70b1d87670 fix: Warn when a Git Sync change cannot be discarded [INS-3830] (#10585)
* fix: Warn when a Git Sync change cannot be discarded [INS-3689]

When a committed YAML file is not in the exact format Insomnia generates
(hand-edited, or written by an older version), discarding it restores the
file, the repo file watcher imports it and re-exports it, and the change
reappears. Users get stuck with a change they can never discard.

Detect this up front by replaying the import -> export round-trip in memory
on the raw index/HEAD content. When the result equals the working copy, the
whole diff is Insomnia re-generating the file, so the Commit Changes modal
shows a warning above the diff and the discard confirmation explains that
the file needs to be committed once.

- Add sync/git/canonical-file.ts, which mirrors database.update (initModel)
  and the getWithDescendants ordering (created, then _id)
- Split getInsomniaV5DataExport into a DB fetch and a pure
  serializeInsomniaV5Export
- Return rawHead/rawStage from GitVCS.fileStatus, since head/stage are
  migrated and reordered for display
- Export initModel from insomnia-data/node

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* refactor: Replay the Git Sync round-trip on a scratch database [INS-3689]

The undiscardable-change check reimplemented parts of the import/export
pipeline (initModel, getWithDescendants ordering) to avoid touching the app
database. That copy would silently drift whenever the real pipeline changes.

Run the real pipeline instead: write the imported docs to a scratch
in-memory NeDB instance and export them with getInsomniaV5DataExport.

- Keep NeDB collections, change buffer and listeners per instance in
  createNedbDatabase. They were module-level, so a second instance's init()
  would have replaced the app's collections. flushChangesImpl is now handed
  to the wrapper instead of being exported.
- Add an optional db parameter to getInsomniaV5DataExport and drop the
  serializeInsomniaV5Export split and the initModel export

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix: Ignore import timestamps when detecting undiscardable changes [INS-3689]

Import fills a missing meta.created/modified with the current time, so a
hand-added entry without timestamps got a different value in the replay
than in the working copy the watcher wrote earlier. The exact comparison
then failed and the warning never showed, although the change still came
back after every discard.

Compare the replay with the working copy using hasSignificantChanges, the
same rules the Unstaged changes list uses, so differences the list already
ignores no longer hide the warning.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* chore: Reword the undiscardable change warning [INS-3689]

Explain the cause in user terms, using the wording suggested in the ticket.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* chore: Shorten the undiscardable change warning [INS-3689]

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* refactor: Rename committedContent to baselineContent [INS-3689]

The content a discard restores is the staged content when there is one, so
it is not necessarily committed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-14 09:53:20 +00:00
Kent Wang 0cb82a2d16 feat: Migrate mcp request and related model types using zod (#10526)
* migrate mcp request and mcp collection schema and definitions

* fix key order issue of mcp request

* remove useless comment

* update schema
2026-10-14 11:00:25 +08:00
Kent Wang b108dbbe58 feat: Migrate mock-server and mock-route zod schema and type definitions (#10520)
* migrate mock-server and mock-route zod schema and type definitions

* modify from comment

* fix sort order and ci failure

* modify comment
2026-10-13 15:59:57 +08:00
Curry Yang 27457eeb93 feat: change data model to support confidential control (#10479)
* feat: add confidential environment variable metadata

* feat: move option

* del tooltip

* update schema
2026-10-13 11:29:06 +08:00
Bingbing ca30fbcc7b fix: regenerate document ids on project storage conversion (#10565)
## Background

Project storage conversion reuses the document ids owned by the previous storage. Known problems:

- Id hijack via global upsert: converted projects keep git YAML ids pulled by RepoFileWatcher or cloud backend ids pulled by cloud sync, and external imports upsert documents globally by their original ids — a later import of the same source overwrites or steals this project's documents.
- Id conflicts block the conversion loop: a project-scoped clone rejects with "The repository being cloned contains workspaces that already exist in Insomnia." when the target project still holds the repository's ids.
- The git FS watcher is not stopped during conversion: an active watcher flushes DB changes (including re-keyed docs) back into the repository files mid-conversion.
- Git → cloud conversion creates no backend resources: no backend project initialization and no snapshot push, so the converted cloud project has nothing syncable.
- Stale workspace-level git state is left behind (gitRepositoryId, gitFilePath, gitFileLastSyncTime, hasUncommittedChanges, hasUnpushedChanges), so the project card keeps showing git status after conversion.
- WorkspaceMeta references are not remapped: the model has no rewriteReferences, so active environment/request/test-suite selections dangle after re-keying.
- Conversion gives no warning that regenerating ids invalidates inso commands, CI scripts and template tags referencing the old ids.

### Repro

1. Create a git project and pull its content.
2. Convert the project to cloud storage.
3. Convert it back to git, pointing at the same repository.

Result: the clone is rejected because the converted project still holds the repo's original workspace ids.

## Changes

- Add regenerateProjectDocIds: re-keys every document under the project's workspaces with fresh ids, remapping parent chains and embedded references (including template tags) via models.rewriteReferences; adds the missing WorkspaceMeta remapper
- Call it on every storage conversion branch of the project update route: local ↔ remote, local ↔ git, remote ↔ git; regeneration runs after the previous storage's watcher is stopped and before the new storage's import
- Stop the FS watcher and clean up the managed repo folder before touching DB docs on git conversions, and clear stale workspace-level git state afterwards
- Initialize cloud sync (initialize backend project + push snapshot) on git → cloud conversions so the re-keyed docs reach the backend with their new ids
- Show a confirmation dialog (AskModal) before any storage conversion in project-settings-form
- Tests: re-keying of nested runtime docs (responses, unit tests), multi-workspace independence, empty workspace, and WorkspaceMeta reference remapping
2026-10-13 02:52:26 +00:00
Insomnia 93e93d5d07 Bump app version to 13.3.1 (#10579) 2026-10-10 11:08:11 +00:00
Kent Wang a17a1a0ebb feat: Unify and migrate environment model to use Zod schema and infer type (#10516)
* unify and migrate environment model using zod and infer type from zod schema
* fix issues from comment
* commit missing parse part
* fix type failures
2026-10-08 16:00:08 +08:00
Kent Wang 098685e514 feat: Add base model schema and deep strict utility (#10515)
* add base model and deep strict utility

* fix deep strict error from comment

* remove unused import
2026-10-08 15:42:07 +08:00
Insomnia 741c638aa8 Bump app version to 13.3.0 (#10552) 2026-09-24 03:47:00 +00:00
yaoweiprcandClaude Sonnet 5 0d549eb8be feat(konnect): move Konnect projects into a global Control Planes organization [INS-3148] (#10315)
* Move Konnect projects into a global Control Planes organization

* fix: break new circular dependency in Konnect organization utils

useKonnectOrganization() imported useRootLoaderData from ~/root to read
accountId, but organization-utils.ts is itself reached from root.tsx via
the settings modal chain, closing a new import cycle flagged by CI's
dependency-cruiser check. Pass accountId in from the caller
(useOrganizations), which already has it, instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Konnect moved onboarding nudge.

* Can sync when the konnect org is empty.

* fix: guard two develop-introduced hooks against the Konnect organization

use-organization-storage-rule.ts and use-remote-files.ts's
useRemoteBackendProjects were added by develop's account-data refactor
after this plan's original API-guard audit, and both issued real
network/IPC calls for the local-only Konnect organization:

- useOrganizationStorageRule called the raw API directly and only
  checked isScratchpadOrganizationId, missing Konnect. Fixed by
  delegating to fetchAndCacheOrganizationStorageRule (which already
  returns the correct local-only rules with no network call) instead
  of gating with `enabled`, since a naive gate would fall back to the
  permissive DEFAULT_STORAGE_RULES and surface Cloud Sync/Git Sync
  inside Control Planes.
- useRemoteBackendProjects had no organization guard at all, firing
  window.main.sync.remoteBackendProjectsOfTeam for an org whose
  projects never have a remoteId. Fixed with an isLocalOrganizationId
  check on its `enabled` gate.

Re-audited every other organizationId-scoped API guard in the plan;
no further gaps found. Plan doc updated with both findings.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix: disable Connect & Sync in Konnect settings modal without entitlement

The modal let a user validate and store a PAT even when the account
lacks the Konnect control-planes entitlement, even though syncing
could never run in that state — the sidebar's Sync button was already
disabled here but the modal's own Connect & Sync button was not.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix: re-fetch Konnect entitlements after logging back into the same account

refreshKonnectAccess deduped by accountId, but signing in never
reloads the renderer, so its module-level guard survives a logout —
and a fresh login into the same account keeps the same accountId,
silently skipping the re-fetch of /v1/user/entitlements.

Key the guard on sessionId instead: a new login always mints a new
session token even for the same account, so this still dedupes the
normal cold-start case (startup call and post-login loader share one
session) while correctly re-resolving after logout/login.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix: navigate away when the Konnect organization becomes invisible

Deleting a user's last Konnect project (one at a time via the project
delete action, or in bulk via Disconnect) could leave them stranded on
a URL for an organization that no longer appears in the dropdown, with
no automatic navigation elsewhere.

Add getKonnectOrganizationEscapeRoute(organizationId), which re-checks
visibility with a fresh local project count (no network call — only
that half can change from a plain NeDB delete) combined with the
last-resolved entitlement, updates the shared access store so
useOrganizations() reflects it immediately, and returns the account's
first real organization to redirect to when the org just went dark.

Call it from both places that can remove the last Konnect project:
- organization.$organizationId._index.tsx's loader, which every
  "no reachable project" fallback already redirects through
- organization.$organizationId.project.$projectId.delete.tsx's
  action, which previously short-circuited straight back into the
  same (now invisible) organization instead of going through that
  loader

Extracted the shared "recompute + store update" logic into
reconcileKonnectAccess() to avoid duplicating it between
refreshKonnectAccess() and the new escape-route check.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Migrate after login

* Force fetch storage rule

* Replace Konnect sync module-var trigger with event bus

Swaps the register/run module variable in konnect-sync-trigger.ts for
uiEventBus so the sync callback is subscribed/unsubscribed via useEffect
instead of being reassigned on every render with no cleanup.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Remove plan

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 09:04:12 +00:00
Kent Wang 095585f5f7 change show test behavior (#10504) 2026-09-15 17:31:44 +08:00
kwburns-kong 582e29f1be fix(INS-3620): tag cookie assignment origin (#10475)
* fix: limit cookie template rendering to manually-set cookies and narrow template file access

* fix: only expand nested templates for variable substitution, not direct tag output

* test: cover OAuth2 access token exposure via the request tag for nested-template regression

* sec: exclude response-sourced cookies from WebSocket/Socket.IO connect rendering

* test: fix mTLS/cert smoke tests relying on secure-read-file path-prefix bug

* test: scope mtls smoke test locator to avoid strict-mode collision

* sec: close hard-link bypass of reserved NeDB database file check

* fix: avoid doubled path separator when allowlisted folder is a filesystem root
2026-09-14 15:56:22 +00:00
Kent Wang 36ac23d851 feat: Merge document and collection workspace and add settings to hide legacy test (#10460)
add initial settings for legacy test
add initial check for legacy unit test suites
show dropdown
remove spec route and merged with default debug page
showing document as collection
remove document term in UI
fix lint issue
fix ut failures
2026-09-10 07:01:24 +00:00
Bingbing a7c5ca4799 feat(SSE): add stream summary extraction for SSE responses (#10455)
[INS-3702](https://konghq.atlassian.net/browse/INS-3702)

## Summary
- Extracts a JSONPath from each streaming SSE message and concatenates it into one readable transcript, shown in a new "Summary" tab next to Events — useful for debugging LLM streaming APIs (OpenAI, Anthropic, Gemini) without scrolling through raw chunks.
- Auto-infers the JSONPath from the request URL for known provider endpoints (OpenAI Chat Completions/legacy Completions/Responses, Anthropic Messages, Google Gemini streamGenerateContent), matched by pathname only (not full URL/host), so self-hosted or reverse-proxied endpoints that keep the same path shape still match. Falls back to a manually-editable path otherwise.
- Handles curl's SSE event log being chunk-granular rather than frame-granular (a JSON payload can span multiple raw network reads, or multiple SSE frames can land in one chunk) by reconstructing the raw wire text and re-parsing `data:` frames properly.
- Handles Gemini's default `streamGenerateContent` response (no `?alt=sse`), which is a single top-level JSON array with no `data:` frames and no blank lines between elements, by scanning the array's bracket/brace depth by hand and pulling out whichever elements have fully closed so far — including mid-stream, before the array's closing `]` (or even the last element's own closing `}`) has arrived — so the summary renders progressively instead of only after the full response finishes.
- Summary tab defaults to selected when the URL matches a known provider, otherwise Events stays default. Plain text/Markdown render toggle for the summary output.
- Scoped to `curl` (SSE) responses only — WebSocket, `socketIO`, and `mcp` responses are untouched.
2026-09-07 08:06:42 +00:00
Bingbing 1b9c08d007 feat(ui): split environment picker into project/collection dropdowns (#10446)
## Summary
- Splits the single "Manage Environments" popover into two independent dropdowns — project-level and collection-level — each with a scope tooltip and an inheritance-order hint (folder overrides collection, which overrides project).
- Replaces the hidden "+" menu in the collection environment editor and the project-level full-page environment editor with explicit, always-visible "Add Sub Environment" / "Add Private Sub Environment" buttons.
- Adds an "Add Project Environment" action to the project dropdown (does not auto-select the new environment).
- Adds a keyboard shortcut for the project dropdown (Cmd/Ctrl+Alt+E), alongside the existing collection-environment shortcut (Cmd/Ctrl+Shift+E).
- Fixes smoke tests broken by removing the old single-picker trigger, and adds new coverage for the split dropdowns and create flows.
2026-09-03 08:52:20 +00:00
xdm 4b121c89f6 refactor(vcs): move vcs to insomnia-vcs (#10427)
refactor(vcs): move vcs to insomnia-vcs

fix: fix comments
2026-08-26 14:37:16 +08:00
Insomnia 1755d42406 Bump app version to 13.2.0 (#10439) 2026-08-25 09:30:13 +00:00
xdm bf982e7895 refactor: move organization to service layer (#10390) 2026-08-25 09:13:41 +00:00
Kent Wang 01fe9b7c7f fix shortcut creation issue & workspace dropdown context menu issue (#10432)
fix action issue

remove use less codes

modify optimistic way to toggle request folder
2026-08-25 01:30:23 +00:00
Jack Kavanaghandkwburns-kong 28e306bb0a PoC: opt-in QuickJS sandbox for pre-request/after-response scripts (#10382)
* poc: opt-in QuickJS sandbox for pre-request/after-response scripts

Adds settings.useQuickJsScriptSandbox (default off) and wires it into the
existing hidden-BrowserWindow dispatch point in concurrency.renderer.ts, so
scripts can optionally run in the QuickJS-WASM sandbox already used for
plugin template tags instead of the hidden window.

This PoC supports console, insomnia.environment/variables get/set, and
read-only insomnia.request; insomnia.sendRequest() and insomnia.test()/
pm.test() are not yet bridged and throw a clear error.

Full rollout plan (worker-boundary move, async host bridge, test-lifecycle
and request-mutation parity, security verification, telemetry/soak, and
eventually flipping the default to opt-out) is written up here:
https://gist.github.com/jackkav/3ebf8768bf84be024a3a138874919354

* fix: address Copilot review feedback on QuickJS script sandbox PoC

- Timeout error now reports the configured duration instead of an epoch
  deadline timestamp.
- insomnia.request is deep-frozen so mutation attempts are silently
  no-ops consistently, rather than appearing to succeed inside the
  script while never reaching the host.
- Fix operator-precedence bug in a test script (?? binds looser than +).
- Add an aria-label to the new sandbox toggle Switch for screen readers.

* poc: move QuickJS script execution to a dedicated Web Worker (PR 1)

Splits run-script-quickjs.ts into:
- quickjs-script-engine.ts: the pure QuickJS execution logic (unchanged
  behavior), runnable from anywhere.
- quickjs-script.worker.ts: a Web Worker entry point that runs the engine
  off the renderer's main thread.
- run-script-quickjs.ts: now a thin client that lazily creates the worker
  (only when useQuickJsScriptSandbox is actually used) and correlates
  postMessage/response pairs by id, matching the existing
  templating-handler.ts/templating.worker.ts pattern used for template
  tags.

A runaway script (e.g. an infinite loop) now blocks only the disposable
worker instead of the renderer's UI thread. A worker-level crash rejects
every in-flight call and the next call gets a fresh worker.

concurrency.renderer.ts is unchanged apart from continuing to import
runScriptInQuickJs by the same name/path.

Ref: PR 1 of the rollout plan — https://gist.github.com/jackkav/3ebf8768bf84be024a3a138874919354

* style: formatting pass on quickjs worker-client test

* poc: async host bridge + insomnia.sendRequest() parity for QuickJS sandbox (PR 2)

Bridges insomnia.sendRequest() to a real HTTP request instead of throwing,
reusing the existing insomnia-templating-worker-database:// fetch protocol
and its network.sendRequestWithoutSideEffects handler (the same one the
template-tag sandbox already uses) rather than adding a second protocol
scheme. This is the same fetch-to-custom-protocol pattern
templating.worker.ts uses to reach the main process from a dedicated Web
Worker, generalized to a second async host bridge inside
quickjs-script-engine.ts (a VM promise resolved off a real fetch(),
settled via executePendingJobs() — no asyncify).

- quickjs-script-engine.ts: installSendRequestBridge() + BOOTSTRAP's
  insomnia.sendRequest() now normalizes a URL string or a plain
  {url, method, headers, body} object, calls the bridge, and rebuilds a
  response object ({code, status, headers, body, responseTime, json(),
  text()}) — supports both the Postman-style (error, response) callback
  and awaiting the returned promise. insomnia.test()/pm.test() still
  throws (unchanged).
- run-script-quickjs.ts (client): fetches the templating-db auth token
  once via window.main.templatingDb.getAuthToken() (same pattern as
  ui/worker/templating-handler.ts) and forwards it on every postMessage.
- quickjs-script.worker.ts: passes the auth token through to the engine.

Known gaps (documented in quickjs-script-engine.ts, deferred to a later
parity PR): no auth/client-certs/cookies/multipart-or-urlencoded bodies,
and the response object doesn't yet match the hidden-window Response
class's full surface (chai assertions, originalRequest, cookies).

Ref: PR 2 of the rollout plan — https://gist.github.com/jackkav/3ebf8768bf84be024a3a138874919354

* Revert "poc: async host bridge + insomnia.sendRequest() parity for QuickJS sandbox (PR 2)"

This reverts commit 37d19c1da8.

* test: add e2e smoke test for QuickJS sandbox (PR 0 + PR 1 only)

Proves the opt-in QuickJS engine and Web Worker boundary work end to
end in the real Electron app, not just in vitest's mocked unit tests:

- console.log, insomnia.environment.get/set, and read-only
  insomnia.request all work through the real Worker/QuickJS pipeline
  (canary: `typeof require` confirms the script actually ran in
  QuickJS, not the legacy hidden-window engine).
- A runaway (`while(true){}`) script blocks only its dedicated Worker —
  the app UI stays responsive and interactive while it churns.

insomnia.sendRequest() (PR 2) is intentionally not exercised — it's
been split into its own WIP branch/PR (#10392) pending a real fix for
a QuickJSUseAfterFree crash that only reproduces under real Electron
timing.

Uses "testQueryParams", a request at the workspace root with no body
and no folder-inherited scripts. Every other candidate in this fixture
either references environment variables undefined until a script runs
(triggering Insomnia's "N environment variables are missing"
confirmation dialog) or inherits a folder-level after-response script
calling an API this minimal engine doesn't bridge, which turns an
otherwise-successful send into a displayed "Error" status. Asserting
via the Console tab (console.log output) instead of an echoed response
body sidesteps template rendering entirely.

Ref: PR 0/1 of the rollout plan — https://gist.github.com/jackkav/3ebf8768bf84be024a3a138874919354

* fix(scripting): guard __proto__/constructor/prototype keys in QuickJS env/var bridge (#10395)

A script-supplied "__proto__"/"constructor"/"prototype" key reaching the bridge's store object could rewire its prototype or shadow those names; the bridge now rejects these keys before assignment.

---------

Co-authored-by: kwburns-kong <kyle.burns@konghq.com>
2026-08-14 17:13:45 +08:00
Ryan Willis 29b2e391fb fix(database): emit change notifications on document duplication (#10387) 2026-08-12 13:29:36 -07:00
kwburns-kong a384cf00c7 fix(deps): security dependency bumps (#10347)
* fix(deps): bump fast-uri to patch host-confusion SSRF vulnerabilities

fast-uri <3.1.5 is vulnerable to host confusion via backslash authority
delimiters and failed IDN canonicalization (GHSA advisories), which can
enable SSRF. ajv and @rjsf/utils already permit fast-uri ^3.x, so this
only required refreshing the lockfile resolution, no parent bump needed.

* fix(deps): bump undici to patch cookie/cache/desync vulnerabilities

undici <7.29.0 is affected by several advisories: Set-Cookie SameSite
downgrade via permissive substring matching, cross-user cache leakage
via whitespace bypass, downstream response desync via retry
interceptor, CRLF injection via blob-like body 'type', and cookie
attribute injection via unsanitized domain fields. The direct
dependency's existing ^7.25.0 range already permitted the fix, so this
only required refreshing the lockfile resolution.

Note: @connectrpc/connect-node@1.7.0 still bundles its own pinned
undici@^5.28.4 (resolves to 5.29.0), which remains vulnerable to the
older <6.24.0 advisories. Fixing that requires a major bump of
connect-node to 2.x, which needs its own review for breaking API
changes - tracked as a follow-up.

* fix(deps): bump builder-util-runtime to patch credential-leak vulnerability

builder-util-runtime <9.7.0 leaks PRIVATE-TOKEN and mixed-case
Authorization credentials on cross-origin redirects during
electron-updater's auto-update flow. electron-builder and
electron-builder-squirrel-windows pinned it exactly at 9.5.1, so
those parents needed bumping (26.8.1 -> 26.15.7) to pull the fix.
electron-updater's existing ^6.6.2 range already permitted 6.8.9,
which resolves the same fixed builder-util-runtime.

* fix(deps): bump liquidjs to patch memoryLimit bypass

liquidjs <=10.27.0's pop filter bypasses the memoryLimit accounting
enforced by its array-filter siblings, allowing a DoS via unbounded
memory growth in template rendering. Both consumers already declare
^10.27.0, which permits the fix, so this only required a lockfile
refresh (resolved to 10.28.0).

* fix(deps): bump ip-address to patch octal/decimal parsing SSRF

ip-address <=10.3.0 decodes Address4 leading-zero octets as decimal
while WHATWG URL host parsing, inet_aton, and getaddrinfo decode them
as octal, letting an attacker bypass IP-based trust boundaries and
achieve SSRF. express-rate-limit@8.3.2 pinned ip-address at an exact
10.1.0, so it needed bumping to 8.6.2 (still within @modelcontextprotocol/sdk's
^8.2.1 range) which declares ip-address ^10.2.0 and resolves to 10.4.0.

* fix(deps): bump tar to patch PAX parsing and recursion DoS issues

tar <=7.5.20 has multiple issues: process crash via PAX numeric path
type confusion, decompression/parse DoS via unlimited input, infinite
loop on negative entry size during archive replace, uncaught exception
via NUL bytes in PAX path/linkpath records, and uncontrolled recursion
in mapHas/filesFilter enabling stack-overflow DoS via crafted long-path
entries. node-gyp and @mapbox/node-pre-gyp already declare tar ^7.5.4 /
^7.4.0, which permit the fix, so this only required a lockfile refresh
(resolved to 7.5.22).

* fix(deps): bump ws to patch tiny-fragment memory exhaustion DoS

ws 8.0.0-8.20.1 bounds retained WebSocket message fragments via
maxFragments/maxBufferedChunks, but the defaults were set too high,
letting an attacker exhaust memory with many tiny fragments/chunks.
The direct ws dependency's ^8.18.1 range already permitted the fix;
socket.io/socket.io-client's bundled engine.io, engine.io-client, and
socket.io-adapter pinned ws with a `~8.20.1` tilde range that excluded
it, so those three needed bumping to pull in `~8.21.0` (still within
socket.io@4.8.3's own ~6.6.0/~6.6.1 ranges). All ws instances now
resolve to 8.21.2.

* fix(deps): bump hono to patch 33 advisories (cookie/CORS/routing/XSS)

hono <=4.12.33 accumulates a long list of fixes: cookie name validation
bypass on write/read paths, path traversal in toSSG() and serve-static
(including Windows backslash encoding), IP restriction bypass for
IPv4-mapped/non-canonical IPv6, JWT NumericDate/Bearer-scheme
validation gaps, cache middleware Vary header leakage, CORS wildcard
credential reflection, JSX SSR XSS via cx(), and a ReDoS in CORS's
Access-Control-Request-Headers handling, among others.
@modelcontextprotocol/sdk's existing ^1.17.5 range already permits
the fix; bumping it to 1.30.0 resolves hono to 4.13.0.

* fix(deps): bump valibot to patch flatten() TypeError on inherited keys

valibot <=1.4.1's flatten() helper throws a TypeError when validation
issues contain attacker-controlled object keys such as toString,
valueOf, or hasOwnProperty. @react-router/dev's existing ^1.2.0 range
already permits the fix, so this only required a lockfile refresh.

* fix(deps): bump dompurify to 3.4.13 (direct dep, lockfile refresh)

Direct dependency's existing ^3.4.10 range already permitted the fix;
this only required a lockfile refresh.

* fix(deps): bump morgan to 1.11.0 (transitive via @react-router/serve)

@react-router/serve@7.15.0's existing ^1.10.1 range already permitted
the fix, so this only required a lockfile refresh. Brings on-finished
along from ~2.3.0 to ~2.4.1 as a nested dependency bump.

* fix(deps): bump uuid from v9 to v11 to patch buffer bounds check

uuid <11.1.1 is missing a buffer bounds check in v3/v5/v6 when a buf
is provided, which can lead to memory corruption. insomnia-data,
insomnia-scripting-environment, and insomnia-smoke-test were still on
^9.0.1 (packages/insomnia already used ^11.1.1). This is a major
version bump, but the only APIs in use across these packages are v4()
and validate(), whose signatures are unchanged between v9 and v11, so
no code changes were needed. All three now resolve to uuid@11.1.1.

* fix(deps): bump csv-parse from v6 to v7

csv-parse 6.x is flagged for update to 7.0.2. This is a major version
bump (ESM/CJS dual-package modernization), but the sync `parse()` API
that packages/insomnia-scripting-environment and the sandbox's
require-interceptor (exposing it to user scripts as
'csv-parse/lib/sync') both rely on is unchanged - verified with an
identical before/after parse() smoke test. No code changes needed.

* fix(deps): bump react-router family to 7.18.2 to patch CSRF/XSS/DoS advisories

react-router 6.0.0-7.18.0 accumulates several advisories: CSRF via
PUT/PATCH/DELETE document requests, open redirect via backslash in
<Link>/useNavigate, RSCErrorHandler missing protocol validation (XSS),
arbitrary constructor injection via deserializeErrors() in SSR
hydration, and unauthenticated DoS via inefficient route matching.
react-router, @react-router/dev, @react-router/fs-routes,
@react-router/node, and @react-router/serve were all exact-pinned at
7.15.0 and needed bumping together (they're a version-locked family)
to 7.18.2 - a non-major fix version per npm audit.

One additional react-router advisory (RSC Mode CSRF Bypass, fixed only
in 8.3.0+) doesn't apply here: this app doesn't use React Server
Components (no react-server-dom-webpack/@vitejs/plugin-rsc usage in
the codebase), so the RSC-specific code path is never exercised.

As a side effect, @react-router/serve's bundled express moved from
4.22.1 to 4.22.2, which also fixes a body-parser DoS advisory
(silently-disabled size limit on invalid `limit` values) for that one
instance. Two other body-parser instances (smoke-test's own express,
and the MCP SDK's bundled express) remain on vulnerable body-parser
versions - tracked as a follow-up.

* fix(deps): bump socket.io-parser to patch zero-attachment memory exhaustion

socket.io-parser 4.0.0-4.2.6 lets a specially crafted packet make the
server wait for a large number of binary attachments and buffer them,
exhausting memory. socket.io@4.8.3's existing ~4.2.4 range already
permitted the fix, so this only required a lockfile refresh.

* fix(deps): bump body-parser (via smoke-test's express) to patch limit-bypass DoS

body-parser <1.20.6 silently disables its size-limit enforcement when
given an invalid `limit` value, allowing a DoS via unbounded request
bodies. insomnia-smoke-test's express (^4.21.2) already permitted the
fix; bumping it to 4.22.2 resolves body-parser to 1.20.6.

Note: @modelcontextprotocol/sdk still bundles express@5.2.1 with a
vulnerable body-parser@2.2.2 (needs >=2.3.0). Left unfixed for now -
Insomnia only uses the SDK's client-side StreamableHTTPClientTransport
(packages/insomnia/src/main/mcp/transport-streamable-http.ts), never
the SDK's server/express code path, so this instance is unreachable
in practice. A prior attempt to patch it via manual lockfile surgery
left package-lock.json in an inconsistent state (a resolved package
missing its "packages" entry, so `npm ci` wouldn't reproduce it) and
was reverted. Tracked as a follow-up to fix through a supported
mechanism (e.g. once @modelcontextprotocol/sdk relaxes its body-parser
range, or via a clean full lockfile regeneration reviewed on its own).

* fix(deps): bump form-data to patch CRLF injection (2 of 3 instances)

form-data <2.5.6 and >=4.0.0 <4.0.6 are vulnerable to CRLF injection
via unescaped multipart field names/filenames. @types/request's
^2.5.5 and jsdom's ^4.0.0 ranges already permitted the fix, resolving
to 2.5.6 and 4.0.6 respectively via lockfile refresh.

Note: httpsnippet@3.0.10 (the latest available release) exactly pins
form-data at 4.0.4, which stays vulnerable. There's no newer
httpsnippet version to bump to yet - this is upstream-blocked, not
fixable without an override. Tracked as a follow-up to revisit once
httpsnippet ships a fix.

* fix(deps): bump @customerio/cdp-analytics-browser to patch nested js-cookie + uuid

Bumps the pinned ^0.3.9 to ^0.5.9. This single bump fixes two
findings that were previously nested inside this analytics SDK and
not independently reachable:
- js-cookie: was exactly pinned at 3.0.1 (<=3.0.5 is vulnerable to a
  per-instance prototype hijack in assign() enabling cookie-attribute
  injection); now ^3.0.7, resolving to 3.0.8.
- uuid: customerio-gist-web bundled uuid@^8.3.2 (missing buffer bounds
  check in v3/v5/v6, <11.1.1); now declares ^14.0.0, resolving to
  14.0.1. This was the residual instance noted as a follow-up in the
  earlier uuid v9->v11 commit.

The AnalyticsBrowser API surface used in use-cio.tsx (load/track/
identify/page/reset) is unchanged between 0.3.19 and 0.5.9.

* fix(deps): bump body-parser to 2.3.0 for the MCP SDK's bundled express

Fixes the remaining body-parser instance (via @modelcontextprotocol/sdk's
express@5.2.1, which declares ^2.2.1 - already permitted the fix).
This is the instance noted as unreachable/deferred in the prior
body-parser commit; the dependency graph has since shifted (from the
react-router and customerio bumps) enough that a plain `npm update
body-parser` now resolves it cleanly via a proper lockfile entry,
unlike the earlier attempt that left a broken lockfile via manual
surgery. All three body-parser instances are now fixed.
2026-08-12 15:55:41 +00:00
Jack Kavanaghandkwburns-kong e3121d28fc refactor(templating): retire templateTagSandboxEnabled, unify on pluginSandboxEnabled (#10364)
* refactor(templating): retire templateTagSandboxEnabled, unify on pluginSandboxEnabled

The experimental `templateTagSandboxEnabled` toggle only ever gated
template-tag execution and had been superseded by `pluginSandboxEnabled`,
which sandboxes every untrusted plugin surface. Retire the legacy flag:

- drop it from the Settings type + defaults
- simplify `isSandboxEnabled` to read only `pluginSandboxEnabled`
- bundle plugins are trusted, so their tags always run in-process (the
  legacy all-modules/all-caps bundle sandbox branch is removed)
- remove the "Run template tags in sandbox" Preferences toggle
- carry a user's prior opt-in forward via a settings migration
  (templateTagSandboxEnabled === true -> pluginSandboxEnabled = true),
  then delete the stale field

Smoke helpers repointed to the surviving `toggle-plugin-sandbox`; the now
-duplicate `enablePluginSandbox` helper is folded into `enableSandbox`.

* refactor(plugins): rename 'trusted' execution mode to 'internal'

'trusted' is an internal-only PluginExecutionMode label for built-in
bundled plugins the user can't install or change; it's never surfaced in
the UI (the Plugins badge shows 'In-process'). Rename it to the more
neutral, descriptive 'internal' to match the docs. Distinct from the
plugin *registry* trust concept (resolveTrustedPlugin, the 'trusted-plugin'
guard), which is unchanged.

* sandbox: reject bundle-plugin name impersonation, remove stale doc (#10376)

* docs(settings): simplify 'Sandbox all plugin code' toggle description

Address review nit: drop implementation jargon (QuickJS-WASM, default-deny)
from the Preferences copy in favour of plain language, keeping the coverage
list and the full-host-access escape-hatch pointer.

---------

Co-authored-by: kwburns-kong <kyle.burns@konghq.com>
2026-08-12 13:36:00 +00:00
James Gatz 814a5aef0c feat(settings): add proxyIntegrations option for first-party integrations (#10363)
* feat(settings): add proxyIntegrations option for first-party integrations

* fix(proxy): improve handling of integration host URLs in insomniaIntegrationHosts function

* feat(proxy): enhance proxy integration handling for various services and update settings help text

* feat(proxy): introduce ProxyScope to manage proxy usage for requests and all traffic

* refactor(proxy): rename ProxyScope to ProxyScopes and update references throughout the codebase
2026-08-11 18:57:33 +03:00
Kent Wang cecbec02d3 Chore: Refine the workspace data hook and add a pending state for sidebar (#10359)
* ts query enhancement

* fix bugs

* fix issues
2026-08-11 03:59:35 +00:00
Pavlos Koutoglou ad268587e9 feat: add sidebar collection focus mode (INS-2912) (#10324)
* feat: add sidebar focus setting for collections in General settings

* feat: add depthOffset prop to EmptyNode and RequestNode for sidebar focus adjustment

* feat: add sidebar collection-focus-mode swipe transitions animations

* feat: clear focus state when exiting collection focus mode

* feat: implement backToAllProjects method and update tests for sidebar navigation

* feat: enhance workspace active state check with polling mechanism

* feat: update cloud sync test to include navigation back to all projects before branch actions

* feat: add sidebar focus mode onboarding with dismissal persistence

* feat: update onboarding text for sidebar focus mode to clarify navigation

* fix: correct typo in onboarding text for sidebar focus mode

* feat: implement seedSettings function to pre-seed settings for tests and update sidebar focus mode onboarding tests
2026-08-10 17:52:17 +00:00
Pavlos Koutoglou a3822e8d30 feat(git): name app-managed git folders after their project instead of a bare hex id (#10349)
* feat(git): implement folderSlug for Git repositories and add slugify utility

* fix(project): wait for modal backdrop to hide before clicking next button

* feat(git): enhance folderSlug validation and path resolution for Git repositories

* fix(git): improve fallback path resolution for git repositories to ensure safety

* fix(project): handle unsaved changes confirmation when closing project modal

* fix(project): handle race condition in unsaved changes confirmation dialog when closing project modal
2026-08-10 20:40:00 +03:00
Kent Wang 6c9f1b60fc feat: Add app data service and enhance the sidebar cache logic (#10333)
* add package

remove workspaceCount from rootLoaderData

move unrelevant loaders out

add query context

adapt tanstack query

fix som issues

add new ways to load data

initial changes

clean code

remove and fix code

add a method to get organization data in main

refine the way to get data from tanstack

fix issue

fix issues

fix duplicate calling issue

fix unsubscribe issue

fix merge issue

fix listen issue

fix find organization issue for workspace

support workspatemeta in tanstack query

update types

move logic to insomnia-data services

remove things

change to use service

fix the loader bug

remove a file

fix type issues

refine code for workspace-children

change style import

fix main type issue

fix type issue

fix data fetching

fix delete project issue

cache the sidebar data in main

add unit tests

update cache and cache service

fix issues from comment

revert organization change

fix issues from comment

fix test failures

fix test failures

add comments and refine way to get workspace children

fix dedup and import issue

remove useless code

add duplicate id check

fix type failures

fix mock server issue

resolve conflict

1.remove main process cache

add renderer level app data

fix issues

* fix issues from review
2026-08-07 08:49:24 +08:00
Kent Wang 5e72ae5806 feat: Persistent link of vault tag with local credential item (#10221)
* add utility function

* fix a comment typo

* generate unique id for vault tag

* fix type issue

* support hint for old credential
2026-08-06 17:11:26 +08:00
Jack Kavanaghandkwburns-kong e759bbceaf feat(templating): (T1) flip trust model — pluginSandboxEnabled + per-plugin elevated opt-in (#10318)
* feat(templating): (T1) pluginSandboxEnabled + per-plugin elevated opt-in, centralized gate

Introduces the trust-model flip's core logic and wires every untrusted-execution surface to it.

- New setting `pluginSandboxEnabled` (default off) that supersedes/absorbs `templateTagSandboxEnabled`:
  either flag on activates the sandbox, so existing template-tag opt-ins keep working (migration bridge).
- New per-plugin `pluginConfig.elevated` escape hatch: a user plugin marked elevated runs in-process
  with full host access even while the sandbox is on. Widened PluginConfig/PluginConfigMap/Plugin.config.
- New pure resolver `common/plugins/sandbox-mode.ts` (isSandboxEnabled / resolvePluginExecutionMode /
  shouldSandboxPlugin) — the single source of truth replacing the 7 duplicated
  `templateTagSandboxEnabled && directory !== ''` conditions. Dependency-free so main, the plugin
  window, and the inso CLI node runtime all share it. Unit-tested (12 cases).
- Wired all surfaces to shouldSandboxPlugin: load-time discovery (now per-plugin, so an elevated
  plugin is nodeRequire-d for live functions), request/response hooks (plugin-window + node runtime),
  actions, and user template tags. Bundle-tag path reads isSandboxEnabled (bundle stays trusted).

No UI yet (next commit); default-off means no behavior change until a flag is toggled.

* feat(templating): (T1) Preferences UI — plugin-sandbox toggle + per-plugin elevated + mode indicator

- Scripting settings: new "Sandbox all plugin code (experimental)" toggle for pluginSandboxEnabled
  (data-testid toggle-plugin-sandbox), beside the existing template-tag toggle.
- Plugins settings: each user plugin card now shows its resolved execution mode
  (Sandboxed / Elevated / In-process, data-testid plugin-mode-<name>) and a "Full host access"
  checkbox (data-testid plugin-elevated-<name>) that writes pluginConfig.<name>.elevated. Mode +
  toggle read from live settings so they update immediately, before the plugin list reloads.
- Widened SerializablePlugin.config to carry the optional `elevated` flag through the bridge.

* test(templating): (T1) e2e — pluginSandboxEnabled sandboxes a user plugin; elevating runs it in-process

Composes the trust-flip's two user-visible behaviors on one action-probe plugin:
- Enabling the new pluginSandboxEnabled toggle (not the legacy template-tag flag) routes the user
  plugin's action into the sandbox (canary reports ranin-sandboxed).
- Toggling "Full host access" in Preferences → Plugins flips the mode indicator to "Elevated" and the
  same action then runs in-process (marker absent, ranin-mainprocess) — the per-plugin escape hatch.
Reuses the sandbox-action-collection.yaml fixture and the established writePlugin/clearPluginToast
helpers; adds enablePluginSandbox + setPluginElevated helpers.

* fix(templating): (T1) close two plugin-registry trust-cache gaps (#10326)

* fix(templating): close two plugin-registry trust-cache gaps

- pluginConfig.elevated is keyed by declared plugin name, not by folder;
  a same-named folder placed alongside an already-elevated plugin
  inherited its trust grant and ran in-process before any collision was
  even noticed. traversePluginPath now pre-scans for duplicate names
  (order-independent) and refuses to load any colliding folder.

- applyRequestHooks/applyResponseHooks tagged a caught error with
  `error.plugin = plugin`, a plain assignment that a plugin-thrown Error
  could intercept via its own `plugin` property setter, handing the hook
  a live, mutable reference to its own cached registry entry and letting
  it flip `directory`/`config.elevated` to defeat later sandboxing.
  Switched to Object.defineProperty, which bypasses any such setter.

* fix(plugins): use relative-path containment check instead of startsWith

A bare .startsWith(base) on a resolved path accepts a sibling directory
whose name happens to prefix-match the base (e.g. /plugins-evil vs
/plugins). Added a shared isContainedIn helper (path.relative, rejects
.. or an absolute result) and applied it to both the existing
plugin-path containment check and the new duplicate-name pre-pass.

* fix(templating): (T1) address Copilot review — skip CLI settings read, scope bundle-tag sandbox to legacy flag

- network-adapter.node.ts: only read services.settings.get() when canSandbox (Electron). The pure-Node
  inso CLI can never reach the sandbox host, so the read was wasted work; pass undefined otherwise
  (shouldSandboxPlugin treats it as off). Both applyRequestHooks and applyResponseHooks.
- templating-worker-database.ts: bundle (first-party/trusted) template tags now sandbox only under the
  legacy templateTagSandboxEnabled experiment, not the new pluginSandboxEnabled. The T1 flag isolates
  *untrusted* plugins; sandboxing trusted bundle tags under it was an unintended behavior change.
  Dropped the now-unused isSandboxEnabled import.

---------

Co-authored-by: kwburns-kong <kyle.burns@konghq.com>
2026-08-05 14:02:45 +00:00
Ryan Willis da0a6f7fe6 chore: bump node-libcurl for electron 43 and windows arm support [INS-3111] (#10305) 2026-07-28 12:12:56 -04:00
Kent Wang 202911041b feat: Add a new option to disable launch browser automatically for MCP oauth workflow (#10266)
* add a option to disable oauth browser auto launch in mcp

* fix issue
2026-07-27 08:18:12 +00:00
Jack Kavanagh 5ff4186a79 feat(templating): (H1) route user-plugin response hooks through the sandbox (PR 10b) (#10286)
* feat(templating): (H1) in-sandbox response-hook API + marshaling

First increment of PR 10b (response hooks). Adds the sandbox-side machinery to
run a user plugin's response hook, without yet wiring the network adapters:

- __buildResponseApi(resp): faithful ES5 rebuild of plugins/context/response.ts
  getters (status/headers/time, case-insensitive getHeader returning
  string|string[]|null). getBody() bridges to the existing response.getBodyBuffer
  path; getBodyStream() throws (a Node Readable can't cross the sandbox); setBody()
  base64-encodes the bytes over a new response.setBody bridge path (no fs in the
  sandbox) and updates bytesContent locally.
- __invokeHook: for response hooks, attaches context.response and a READ-ONLY
  context.request (matches pluginRequest.init(..., true)), and marshals both the
  request and response back out.
- host-bridge: response.setBody mapped at baseline (models.read, grouped with the
  other response ops) — a bounded write to the host-set bodyPath, matching the
  ungated in-process behavior; not a general fs write.

Unit test drives a response hook that reads status/headers, reads the body via
the bridge, and rewrites it via setBody (asserting the base64 round-trip and the
read-only request). Host runner + adapter integration + e2e are the next increment.

* feat(templating): (H1) route user-plugin response hooks through the sandbox

Wires the response-hook sandbox core into both hook paths so a user plugin's
response hook runs in QuickJS (bundle plugins and the flag-off path unchanged).

- templating-worker-database: runResponseHookInSandbox + the
  plugin.runUserResponseHook handler; the response.setBody bridge handler
  (base64-decode -> fs.writeFileSync) guarded to the responses directory as
  defense in depth (bodyPath is host-set); pickHookResponseFields.
- network-adapter.node.ts (main/CLI): runs the response hook in the sandbox for
  user plugins, merging the returned response fields onto newResponse.
- invoke-method.ts (plugin window): reaches the same runner over the protocol.

E2E: a user plugin response hook rewrites the body via setBody; the echo
response pane shows the rewrite. Flag off it reports ranin-mainprocess (control),
flag on ranin-sandboxed. Completes H1 (request hooks in PR 10a).

* fix(templating): (H1) revive bridged Buffer in response getBody + reject empty setBody

Addresses Copilot review on #10286:
- in-sandbox-bootstrap.ts: context.response.getBody() now revives the JSON-marshaled
  Buffer shape ({ type: 'Buffer', data: [...] }) back into a (shimmed) Buffer, so hooks
  consume it exactly like the in-process response API instead of a plain object.
- templating-worker-database.ts: response.setBody rejects a missing/non-string bodyBase64
  (TypeError) instead of defaulting to '' — a write primitive must not silently truncate
  the body to zero bytes. An empty string stays a valid empty body.
- sandbox-hooks.test.ts: the getBodyBuffer stub now returns the real marshaled Buffer
  shape and the hook decodes with toString('utf8'), exercising the revive end-to-end.
2026-07-24 10:57:40 -04:00
Insomnia 2fcbf833a6 Bump app version to 13.1.0 (#10296) 2026-07-24 09:50:49 +08:00
Bingbing 8a1dc1ef62 perf: rewrite command palette search to eliminate UI freezes and stale results (#10257)
* perf: rewrite command palette search to eliminate UI freezes and stale results

Problems fixed:
- clientLoader blocked navigation on every palette open, freezing the UI during
  full sequential DB scan
- no AbortController: stale searches could overwrite newer results mid-type
- no debounce: every keystroke triggered a full DB traversal immediately
- React Aria's default contains filter re-filtered server-side fuzzy results,
  silently dropping valid matches and making fuzzy work redundant
- no warm baseline: palette started blank until the entire load completed

Changes:
- move fuzzyMatch/fuzzyMatchAll → insomnia-data/common-src/search.ts (shared,
  testable in node)
- move search logic → insomnia-data/node-src/services/helpers/command-search.ts
  - per-request AbortController cancellation via abort(requestId)
  - recursion depth guard (max 20) on request group traversal
  - safeParent() replaces non-null assertions, safe against orphaned documents
- add CommandSearchResult type in insomnia-data/src/command-search-types.ts
- add useCommandSearch hook: 250ms debounce + abort on filter change + warm
  baseline on mount
- add defaultFilter={() => true} to ComboBox, delegating all filtering to the
  service
- delete routes/commands.tsx

* fix

* fix
2026-07-17 01:07:38 +00:00
Jack Kavanagh 3842690f60 feat(templating): vetted npm libraries in the sandbox — uuid + ajv (M3) (#10244) 2026-07-16 12:53:23 +03:00