Skip to content

feat(desktop): settings phase 3a - keyboard layout strategy - #6289

Merged
jamesgeorge007 merged 7 commits into
patchfrom
common-feat-keyboard-layout-strategy-schema
May 12, 2026
Merged

feat(desktop): settings phase 3a - keyboard layout strategy#6289
jamesgeorge007 merged 7 commits into
patchfrom
common-feat-keyboard-layout-strategy-schema

Conversation

@CuriousCorrelation

@CuriousCorrelation CuriousCorrelation commented May 7, 2026

Copy link
Copy Markdown
Member

Phase 3a of the keyboard work in the Desktop App Settings &
Customization epic. Adds a keyboardLayoutStrategy setting to
DesktopSettings, refactors the in-page and capture-phase shortcut
dispatch to honor it, and exposes a Keyboard group with a three-option
radio in the Desktop section of the settings page. The default
("Smart") prefers the typed letter and falls back to the physical key
position for non-Latin layouts, so AZERTY's "A" keycap fires Ctrl+A
and Cyrillic users still get Ctrl+Q from the physical Q position.

Closes FE-1232
Closes FE-1233
Closes FE-1234
Closes FE-1241
Closes #5787
Closes #6090
Closes #6120
Refs #6192
Follow-up on #5944

What it does

The settings store gains
keyboardLayoutStrategy: "key" | "code" | "hybrid" with "hybrid" as
the default. Zod's parse-time defaults handle existing users
automatically, so no explicit migration is needed.

getPressedKey in helpers/keybindings.ts now reads the active
strategy from a small holder (helpers/keyboard-strategy.ts) and
dispatches letter and digit lookups through it. The hybrid strategy
prefers event.key when it produces a Latin glyph and falls back to
event.code otherwise. The key and code strategies are escape
valves for users on layouts where the heuristic guesses wrong. Arrow
keys, Tab, brackets, and the "?" → "/" mapping are layout-stable and
apply unchanged regardless.

The capture-phase keydown listener in selfhost-web/main.ts (which
intercepts desktop-shell shortcuts like Cmd+Q before the in-page
handler sees them) routes through the same resolver. Previously each
shortcut hardcoded its event.code check, so an AZERTY user pressing
the keycap labelled A (physical KeyQ position) fired Cmd+Q and quit
the app instead of selecting all (#6090, #6120). The capture path now
respects the strategy, so the user's choice in settings takes effect
everywhere a shortcut might fire.

Both handlers also skip:

  • IME composition (ev.isComposing || ev.keyCode === 229), so a CJK
    user's keystrokes during composition don't trigger shortcuts.
  • AltGr presses (ev.getModifierState("AltGraph")), so QWERTZ users
    typing [ via AltGr+8 don't get hijacked into the Ctrl+Alt+[ MRU
    shortcut ([bug]: Cannot make [ ] in query parameters #5787). AltGraph is true only for AltGr, never for
    genuine Ctrl+Alt presses.

The settings UI gains a Keyboard group with a three-option radio:
Smart (recommended), Typed letter, Physical key position. Each option
carries a one-line description so users can pick without trial and
error. Selection writes to keyboardLayoutStrategy through the
desktop settings composable, which mirrors it into the holder eagerly
so the next keypress respects the change without waiting for the
store-watch round-trip.

Backwards compatibility

Existing users with no setting saved get the new "hybrid" default on
upgrade. Behaviour shifts from #6009's pure-event.code resolution
to hybrid, which closes the AZERTY bug (#6090) and keeps the Cyrillic
fix (#5944) intact. Users who want the prior physical-position
behaviour can pick "Physical key position" in the new radio.

Fresh installs land on "hybrid" the same way.

The web build keeps the holder at its module-level default ("hybrid")
because the desktop settings composable (the only writer) doesn't run
on web. Web users get the same recommended behaviour as desktop users
who haven't touched the radio.

Tests

Adds 38 vitest cases for resolvePressedKey covering all three
strategies across QWERTY, AZERTY, QWERTZ, Cyrillic, Dvorak, and Mac
Option dead key fixtures, plus layout-stable keys (arrows, brackets,
Tab, Enter) and numpad cases.

End-to-end testing on the Tauri shell against each layout is done
on Windows, Linux and MacOS - FE-1244.

Notes for reviewers

Bracket detection in resolvePressedKey runs before the digit branch
deliberately. AZERTY's [ via AltGr+5 has event.code === "Digit5"
but event.key === "[". Without the early bracket check, the digit
branch would resolve to "5" and a ctrl-alt-5 binding would fire
instead of letting [ through.

The capture-phase listener and the in-page handler share the same
resolver, so the user's strategy choice takes effect everywhere.

getKeyboardLayoutStrategy is a plain getter in a helpers file so
the hot path doesn't pay reactivity cost on every keystroke. The
composable updates the holder eagerly inside update() and from the
store-watch callback so the reactive UI and the holder stay coherent.

The architecture is a strategy dispatch rather than a single
heuristic. The same event.code-vs- event.key question keeps
reappearing in the issue tracker (#3058, #3332, #5944, #6009, #6090, #6120, #6192).
Letting users pick once retires that question instead
of picking the next lost.

VS Code patterns: hybrid dispatch (key first, code fallback)
as the recommended default, AltGraph detection for distinguishing
AltGr-typed symbols from Ctrl+Alt shortcuts, and IME composition
guard for CJK input.

Future work

Per-shortcut rebinding (Phase 3b, FE-1235 through FE-1240) lets
users rebind any registered action through a UI table. The schema
supports it now (the holder pattern extends to a per-action lookup),
but the recorder, bindings table, and conflict detection ship in a
follow-up.

Native menu accelerator integration (FE-1242) brings Tauri's native
Edit menu (added in #5920) under the same strat.

Component-level keydown handlers in spotlight, EnvInput, SchemaSearch,
and the AI modals (FE-1246, audit) currently bypass
helpers/keybindings.ts. Routing them through the registry comes
after too.


Summary by cubic

Adds a desktop keyboardLayoutStrategy setting to match shortcuts by typed letter or by physical key, with a Smart default. Both in‑page and capture‑phase handlers use the same resolver, and saved choices now load at desktop boot. Implements phase 3a of the Desktop Settings & Customization epic (FE-1232, FE-1233, FE-1234, FE-1241).

Written for commit 1969d66. Summary will update on new commits.

Schema field for the future user-facing
radio. Default 'hybrid' will preserve
the dispatch refactor's behavior, and
the current code path is unaffected.

Zod's parse-time defaults handle existing
users automatically, so no explicit
migration is needed.
Refactors getPressedKey to read the
keyboard layout strategy from a small
web-safe holder, replacing the single
event.code path with a per-strategy
dispatch.

The hybrid strategy prefers event.key
when it produces a Latin glyph and falls
back to event.code for non-Latin layouts,
which is the recommended default. The key
and code strategies are escape valves.

Letter and digit branches are the only
ones that dispatch. Arrow keys, brackets,
and the ?-to-/ mapping are layout stable
and apply unchanged regardless.

The desktop settings composable updates
the holder on initial load, on store
watch events, and eagerly inside update()
so changes take effect on the next
keypress.

Skip shortcut handling during IME
composition (CJK input) and when AltGr
is the modifier, so a Ctrl+key combo
that's actually part of typing doesn't
fire a shortcut.

Adds vitest coverage for all three
strategies across QWERTY, AZERTY,
QWERTZ, Cyrillic, Dvorak, and Mac
Option dead key fixtures, plus
layout-stable keys and numpad cases.
The capture-phase keydown listener in
selfhost-web/main.ts hardcoded each
shortcut against event.code, so on
AZERTY a user pressing the keycap
labelled A (physical KeyQ position)
fired Ctrl+Q and quit the app instead
of selecting all (#6090, #6120).

Routes the listener through the shared
resolvePressedKey + active strategy so
the same dispatch the in-page handler
uses applies to capture-phase too. The
hardcoded e.code === "KeyQ" checks
become key === "q" after resolution,
which respects the user's strategy
choice and matches what the user
typed.

Also adds the same IME composition and
AltGraph guards as the in-page handler.
The AltGraph guard closes #5787: on
QWERTZ the user typing [ via AltGr+8
no longer triggers the Ctrl+Alt+[ tab
shortcut.

Closes #5787, #6090, #6120.
Adds a Keyboard group to the Desktop
section of the settings page with three
radios: Smart (recommended), Typed
letter, and Physical key position.
Each option carries a one-line
description so users can pick without
trial and error.

The group label completes the choice
("Match shortcuts by typed letter or
physical position") and a helper
paragraph names the situation in plain
terms so users on AZERTY, QWERTZ, or
Cyrillic see why the choice exists.

Selection writes to the
keyboardLayoutStrategy field through
the desktop settings composable.
Changes apply on the next keypress.

Updates the section description so a
new user reading the page header sees
what's actually configurable here:
update behavior and keyboard handling.

i18n keys for the group title, the
strategy label and helper, and per-
option labels and descriptions.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 9 files

Comment thread packages/hoppscotch-common/src/composables/desktop-settings.ts
@greptile-apps

greptile-apps Bot commented May 7, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR introduces a keyboardLayoutStrategy setting ("key" | "code" | "hybrid") to DesktopSettings and routes all shortcut resolution — both the in-page handler and the Tauri capture-phase listener — through a shared resolvePressedKey function that respects the active strategy. It also adds IME-composition and AltGr guards to both handlers.

  • New keyboard-strategy.ts module holds a module-level singleton for the active strategy, keeping keybindings.ts free of Tauri imports so web builds are unaffected. The composable hydrates the holder eagerly on load, on update(), and on rollback, maintaining coherence with the reactive settings object.
  • resolvePressedKey refactor exports the key-resolution logic for testability, dispatches letters/digits through the selected strategy, and preserves the existing fallback for synthetic events with empty event.code under the "code" strategy — addressing the previously noted silent-drop issue.
  • Capture-phase listener cleanup in main.ts consolidates the redundant per-branch preventDefault/stopPropagation calls into a single post-match block and removes the hard-coded event.code checks, fixing the AZERTY quit-instead-of-select-all regression.

Confidence Score: 5/5

Safe to merge — the strategy dispatch is well-isolated, the singleton pattern is consistent with existing composables, and all three resolution paths are covered by 38 new tests.

The refactor correctly addresses the AZERTY quit-instead-of-select-all regression, restores the synthetic-event fallback that was flagged in a previous review, and consolidates both shortcut handlers through the same resolver. The empty-code fallback for the "code" strategy is explicitly tested, the AltGr and IME guards are in the right order, and the transactional rollback in the composable includes the strategy holder, preventing in-memory drift after a failed persist.

No files require special attention.

Important Files Changed

Filename Overview
packages/hoppscotch-common/src/helpers/keybindings.ts Refactors getPressedKey into an exported resolvePressedKey that accepts an explicit strategy; adds IME and AltGr guards; preserves the empty-code fallback for the "code" strategy; bracket and arrow keys remain strategy-independent as documented.
packages/hoppscotch-common/src/helpers/keyboard-strategy.ts New module-level singleton holder for KeyboardLayoutStrategy; defaults to "hybrid"; exposes plain getter/setter so keybindings.ts stays web-safe without Tauri imports.
packages/hoppscotch-common/src/composables/desktop-settings.ts Hydrates the keyboard-strategy holder after initial load, from the store-watch callback, on optimistic update, and on rollback — keeping the holder in sync with in-memory state across all code paths.
packages/hoppscotch-selfhost-web/src/main.ts Capture-phase listener now uses resolvePressedKey with the live strategy; adds IME and AltGr guards; consolidates redundant preventDefault/stopPropagation calls into a single post-match block; calls useDesktopSettings() early for holder hydration.
packages/hoppscotch-common/src/platform/desktop-settings.ts Adds keyboardLayoutStrategy Zod field with "hybrid" default; existing users automatically get the new recommended default on upgrade via Zod parse-time defaults.
packages/hoppscotch-common/src/components/settings/Desktop.vue Adds Keyboard section with three HoppSmartRadio options backed by a computed array; selection calls setKeyboardStrategy which delegates to the composable's transactional update.
packages/hoppscotch-common/src/helpers/tests/keybindings.spec.ts 38 new vitest cases covering all three strategies across QWERTY/AZERTY/QWERTZ/Cyrillic/Dvorak, layout-stable keys, numpad, synthetic events with empty code, and edge cases.
packages/hoppscotch-common/locales/en.json Adds 9 i18n keys for the new Keyboard settings section and updates the desktop section description.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    EV[Keyboard event] --> IME{IME composing?}
    IME -->|yes| SKIP1[Ignored]
    IME -->|no| ALTGR{AltGr modifier?}
    ALTGR -->|yes| SKIP2[Ignored]
    ALTGR -->|no| RESOLVE[resolvePressedKey with active strategy]

    RESOLVE --> STRAT{Strategy}
    STRAT -->|typed-letter| LK[letterFromKey]
    STRAT -->|physical-code| LC[letterFromCode or empty-code fallback]
    STRAT -->|smart-hybrid| LH[letterFromKey then letterFromCode]

    LK --> MATCH{Match found?}
    LC --> MATCH
    LH --> MATCH

    MATCH -->|yes| LETTER[Return letter]
    MATCH -->|no| STABLE[Layout-stable keys: arrows, tab, enter, slash, dot]
    STABLE --> BKEY{Bracket from typed char?}
    BKEY -->|yes| RBKEY[Return bracket]
    BKEY -->|no| BCODE{Bracket from physical code?}
    BCODE -->|yes| RBCODE[Return bracket - strategy-independent]
    BCODE -->|no| DIGIT[Digit dispatch by strategy]
    DIGIT --> NUMPAD{Numpad plus NumLock?}
    NUMPAD -->|yes| RNUMPAD[Return numpad digit]
    NUMPAD -->|no| NULL[null - no match]

    LETTER --> CAPTURE{Capture phase shortcut?}
    RBKEY --> CAPTURE
    RBCODE --> CAPTURE
    RNUMPAD --> CAPTURE

    CAPTURE -->|matched| EMIT[preventDefault, emit Tauri event]
    CAPTURE -->|no match| INPAGE[In-page handler invokes action]
Loading

Reviews (3): Last reviewed commit: "fix(common): tone down keyboard-strategy..." | Re-trigger Greptile

Comment thread packages/hoppscotch-common/src/helpers/keybindings.ts
Copilot AI review requested due to automatic review settings May 7, 2026 05:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Implements phase 3a of desktop keyboard shortcut layout handling by introducing a keyboardLayoutStrategy setting and routing both in-page and capture-phase shortcut detection through a shared resolver.

Changes:

  • Added keyboardLayoutStrategy: "key" | "code" | "hybrid" to desktop settings (default: "hybrid"), plus a module-level holder getter/setter.
  • Refactored shortcut key resolution into resolvePressedKey and updated both keydown handlers to honor the active strategy while skipping IME composition and AltGr.
  • Added desktop settings UI radios for selecting the strategy and introduced Vitest coverage for resolver behavior.

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/hoppscotch-selfhost-web/src/main.ts Capture-phase shortcut handler now resolves keys via shared strategy-aware resolver and adds IME/AltGr guards.
packages/hoppscotch-common/src/platform/desktop-settings.ts Adds keyboardLayoutStrategy to the desktop settings schema with a default.
packages/hoppscotch-common/src/helpers/keyboard-strategy.ts Introduces a web-safe module-level holder for the active layout strategy.
packages/hoppscotch-common/src/helpers/keybindings.ts Adds IME/AltGr guards and introduces resolvePressedKey strategy-based resolution.
packages/hoppscotch-common/src/helpers/tests/keybindings.spec.ts Adds Vitest cases covering key resolution for multiple layouts/strategies.
packages/hoppscotch-common/src/composables/desktop-settings.ts Mirrors settings changes into the strategy holder eagerly and on external updates.
packages/hoppscotch-common/src/components/settings/Desktop.vue Adds settings UI (radio group) for selecting keyboard layout strategy.
packages/hoppscotch-common/locales/en.json Adds new i18n strings for the keyboard strategy UI and updates desktop description.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/hoppscotch-common/src/helpers/keybindings.ts
Comment thread packages/hoppscotch-selfhost-web/src/main.ts
Comment thread packages/hoppscotch-common/src/helpers/keybindings.ts Outdated
The resolver's bracket branch only matched
event.key === "[" / "]". On Russian Cyrillic
the physical [ keycap types "х" and the ]
keycap types "ъ", so users on Cyrillic
couldn't fire ctrl-alt-[ or ctrl-alt-] from
their keyboard. Adds the BracketLeft and
BracketRight code fallback so the shortcut
resolves regardless of what the active layout
types from those keys.

Also restores the pre-strategy resolver's
synthetic-event fallback for the "code"
branch. When event.code is empty (synthetic
events, certain older environments),
letterFromCode is null and the function used
to return null under "code" strategy,
silently dropping the shortcut. The "code"
branch now falls back to event.key for ASCII
letters, matching what the resolver did
before strategy dispatch.

Exports KeyboardEventLike alongside the
function since it appears in the public
signature, and updates the JSDoc to name
both call sites (getPressedKey and the
capture-phase listener in selfhost-web/main.ts)
instead of "exported for tests".

Tests cover the new bracket fallback under
all three strategies (Cyrillic { key: "х",
code: "BracketLeft" } resolves to "[", same
for "ъ"/"]") and the synthetic-event fallback
under each strategy.
The keyboard-strategy holder is written by
the desktop settings composable's loadInitial.
The composable's only caller was Desktop.vue's
setup, so the holder stayed at its module-
level default ("hybrid") until the user opened
the settings page. A persisted "key" or
"code" choice was ignored on every restart
until then.

Calls useDesktopSettings() inside
setupDesktopUI() in selfhost-web/main.ts so
loadInitial fires at desktop boot and the
holder picks up the persisted choice before
any keypress fires.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 9 changed files in this pull request and generated no new comments.

…ention

The strategy description paragraph used `text-secondaryDark`, giving it
visual weight close to the `<h4>` "Keyboard" title above. Other settings
panels use `text-secondaryLight` for description paragraphs under their
subsection title (see `settings.vue` General/Theme/Kernel Interceptor
descriptions and `Agent.vue`/`Native.vue` proxy labels).
@jamesgeorge007
jamesgeorge007 merged commit e04ef44 into patch May 12, 2026
3 checks passed
@jamesgeorge007
jamesgeorge007 deleted the common-feat-keyboard-layout-strategy-schema branch May 12, 2026 08:03
arun-ford added a commit to Ford/hoppscotch that referenced this pull request Jun 29, 2026
* chore: bump version to `2026.3.1`

* chore: patch axios CVEs and bump related dependencies (hoppscotch#6131)

Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* Delete .github/workflows/codeql-analysis.yml

* refactor(cli): match test-result helper name to documented contract (hoppscotch#6122)

Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* feat(backend): use stateless OAuth2 state store (hoppscotch#6098)

* fix(common): handle non-string values in Postman collection import (hoppscotch#6137)

Co-authored-by: atharvasingh7007 <singhatharva7007@gmail.com>
Co-authored-by: XHamzaX <hamzaswitch1221@gmail.com>
Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* chore(common): remove unused `flow` import

* fix(common): correct environment locale wording (hoppscotch#6117)

Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* fix(data): make `$randomUUID` predefined variable RFC 4122 compliant (hoppscotch#6125)

Co-authored-by: hconsulting987654321-blip <hconsulting987654321-blip@users.noreply.github.com>
Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* chore(common): complete missing Spanish translations (hoppscotch#6109)

Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* chore(common): complete missing Turkish translations (hoppscotch#6071)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* chore(common): modify Chinese translation of words (hoppscotch#5996)

Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* fix(common): add missing aria-labels to icon-only sidenav links (hoppscotch#6160)

Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* fix(common): variable hover tooltip was not clickable (disappeared) (hoppscotch#6155)

* feat: add SMTP OAuth2 authentication support (hoppscotch#6141)

Co-authored-by: nivedin <nivedinp@gmail.com>
Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* fix: improve environment validation in published docs (hoppscotch#5962)

* feat(common): improve API documentation publishing UX (hoppscotch#6116)

Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* fix: remediate `quinn-proto` vulnerability across native packages (hoppscotch#6174)

Co-authored-by: orbisai0security <242526317+orbisai0security@users.noreply.github.com>

* docs: security threat model and policy update (hoppscotch#6158)

Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* fix(common): apply platform default proxy URL on load and reset (hoppscotch#6142)

* feat: add collection-level pre-request and test scripts (hoppscotch#5745)

Co-authored-by: nivedin <nivedinp@gmail.com>
Co-authored-by: “mirarifhasan” <arif.ishan05@gmail.com>
Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* fix(common): support `id_token` in Authorization Code OAuth flow (hoppscotch#6144)

* feat(desktop): settings phase 0 - infra and update check (hoppscotch#6172)

Co-authored-by: VicenzoMF <81040684+VicenzoMF@users.noreply.github.com>

* feat(selfhost-web): make webapp-server timeouts configurable (hoppscotch#6147)

Signed-off-by: Rodrigo Kellermann <kellermann@gmail.com>
Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* chore: bump version to `2026.4.0`

* chore: bump CLI version

* chore: formatting updates

* fix(common): restore magic-link sign-in flow on cloud for orgs (hoppscotch#6237)

* fix(desktop): unified store scope and migration reroute (hoppscotch#6238)

Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* chore: security patch for the dependency chain `v2026.4.0` (hoppscotch#6191)

Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* chore(agent): bump version to `v0.1.17`

* chore(common): add token_refresh auth event and harden no-sync flag

* fix(backend): harden onboarding config endpoint (hoppscotch#6240)

Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* fix(common): set domain url  as mockserver environment (hoppscotch#6185)

* fix(common): subfolder add-new in team collections respects write access (hoppscotch#6243)

* fix(common): preserve string contract for GQL history responses (hoppscotch#6244)

* fix(cli): ship `semver` as a runtime dependency (hoppscotch#6257)

* fix(security): prevent mass assignment in onboarding (hoppscotch#6171)

* fix(backend): prevent mass assignment in onboarding config endpoint

The unauthenticated POST /v1/onboarding/config endpoint mapped the
request body directly to InfraConfigEnum keys, allowing an attacker on
a fresh install to inject sensitive values such as JWT_SECRET and
SESSION_SECRET, enabling forged admin JWTs and full takeover.

Four independent weaknesses combined to make this exploit possible.
This commit addresses each in layers so the fix holds even if any
single layer regresses:

- main.ts: enable `whitelist: true` on the global ValidationPipe so
  properties not declared on any DTO are stripped before reaching any
  controller / service. This is the primary mitigation described in
  the advisory.

- onboarding.controller.ts: scope an additional ValidationPipe
  (`whitelist` + `forbidNonWhitelisted`) on the onboarding POST body
  so requests containing unknown fields are explicitly rejected with
  400 instead of silently dropped.

- infra-config.service.ts (updateOnboardingConfig): introduce an
  `ONBOARDING_ALLOWED_KEYS` allowlist so any `InfraConfigEnum` key
  not part of the documented onboarding surface (OAuth, SMTP) is
  dropped server-side before being persisted, even if earlier layers
  regress.

- infra-config.service.ts (validateEnvValues): explicitly reject
  `JWT_SECRET`, `SESSION_SECRET` and `ALLOW_SECURE_COOKIES` so these
  keys can never be written through any infra-config code path,
  replacing the prior `default: break` behaviour that silently
  accepted them.

Fixes GHSA-j542-4rch-8hwf

* fix(backend): harden onboarding config validation and add sensitive infra-config tests

* chore: cleanup

* chore: class validator implemented in dto layer

* fix: arguments

* fix: api feedback

---------

Co-authored-by: “mirarifhasan” <arif.ishan05@gmail.com>

* fix: class validator decorator usages (hoppscotch#6293)

* fix: class validator decorator usages

* fix: feedback

* fix: preserve script imports and avoid WebKit lookbehind (hoppscotch#6306)

* feat(desktop): settings phase 3a - keyboard layout strategy (hoppscotch#6289)

Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* chore: bump version to `2026.4.1`

* chore(cli): bump version to `0.31.1`

* chore(cli): bump version to `0.31.2`

* chore: security patch for the dependency chain `v2026.5.0` (hoppscotch#6338)

Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* fix: stop secret variable values from leaking to backend (hoppscotch#6279)

Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* fix(common): wait for proxy settings before issuing requests (hoppscotch#6333)

* feat: make proxy URL configurable from env and admin dashboard (hoppscotch#6336)

Co-authored-by: nivedin <nivedinp@gmail.com>
Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* feat(desktop): zoom level control in settings (hoppscotch#6358)

Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* feat(common): add OpenAPI 3.1 collection export (hoppscotch#5880)

Co-authored-by: gavin mcdonough <mcdgavin@users.noreply.github.com>
Co-authored-by: nivedin <nivedinp@gmail.com>
Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* fix(desktop): align appload types and resolve shell import alias (hoppscotch#6369)

Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* chore: bump version to `2026.5.0`

* chore: enforce `minimumReleaseAge` for supply chain hardening

* fix: class validation issue for updateRESTUserRequest (hoppscotch#6373)

* fix: class validation issue for updateRESTUserRequest

* test: modified user-req unit test cases

* feat: add Mongolian translation (hoppscotch#6344)

Co-authored-by: cf3901646 <cf3901646@users.noreply.github.com>
Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>

* fix(common): preserve collection tree on OpenAPI re-import (hoppscotch#6376)

* fix(test-runner): restore missing closing braces in runTestsWithIterations after merge conflict resolution

* fix(test-runner): fix Run Collection - rename runTestsWithIterations to runTestCollection and wire inherited scripts through runTestsInCustomOrder

---------

Signed-off-by: Rodrigo Kellermann <kellermann@gmail.com>
Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Liyas Thomas <liyascthomas@gmail.com>
Co-authored-by: Basavaraj_m_n <162813862+Basavaraj8143@users.noreply.github.com>
Co-authored-by: Mir Arif Hasan <arif.ishan05@gmail.com>
Co-authored-by: okxint <130782884+okxint@users.noreply.github.com>
Co-authored-by: atharvasingh7007 <singhatharva7007@gmail.com>
Co-authored-by: XHamzaX <hamzaswitch1221@gmail.com>
Co-authored-by: Pallav Sarkar <pallav2005sarkar@gmail.com>
Co-authored-by: BUNGHUNTER2026ILOVEYOUECHO <hconsulting987654321@gmail.com>
Co-authored-by: hconsulting987654321-blip <hconsulting987654321-blip@users.noreply.github.com>
Co-authored-by: Franco Ortiz <fr.dv.ortiz@gmail.com>
Co-authored-by: Serhat <49079271+onwp@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Denny Jiang <1632856+jiangzm@users.noreply.github.com>
Co-authored-by: Rishu ray <rayrishu19@gmail.com>
Co-authored-by: Aaron Fort Garcia <aaronfortg@gmail.com>
Co-authored-by: nivedin <nivedinp@gmail.com>
Co-authored-by: sahilkhan09k <Msahilkhan05052005@gmail.com>
Co-authored-by: Nivedin <53208152+nivedin@users.noreply.github.com>
Co-authored-by: Shreyas <CuriousCorrelation@gmail.com>
Co-authored-by: orbisai0security <242526317+orbisai0security@users.noreply.github.com>
Co-authored-by: John An <junghyunan0319@gmail.com>
Co-authored-by: Anwarul Islam <anwaarulislaam@gmail.com>
Co-authored-by: VicenzoMF <81040684+VicenzoMF@users.noreply.github.com>
Co-authored-by: Rodrigo Kellermann <rkferreira@gmail.com>
Co-authored-by: Nahid Hasan <52489202+nahidhasan94@users.noreply.github.com>
Co-authored-by: Gavin McDonough <gavincmcd@gmail.com>
Co-authored-by: gavin mcdonough <mcdgavin@users.noreply.github.com>
Co-authored-by: Charlie Freeman <cf3901646@gmail.com>
Co-authored-by: cf3901646 <cf3901646@users.noreply.github.com>
Co-authored-by: arunkumarjeevanantham <aj34@ford.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants